Hierarchy:

- Tool
	- Script
	- LocalScript
	- RemoteEvent

Server Script:

local tool		= script.Parent
local lib		= require(game.ServerStorage.Library)
local detain	= tool:WaitForChild("Detain")
local detained	= {}
local detainedChar
local connections = {}

local function removeTools(chr)
	for _,obj in next, chr:GetChildren() do
		if obj:IsA("Tool") or obj:IsA("HopperBin") then
			wait()
			obj.Parent	= game.Players:GetPlayerFromCharacter(chr).Backpack
		end
	end
end

local function setCanCollide(chr, bool)
	for _,obj in next, chr:GetChildren() do
		if obj:IsA("BasePart") then
			obj.CanCollide = bool
			print(obj.Name.." is now set CanCollide to "..tostring(bool))
		end
		setCanCollide(obj, bool)
	end
end

detain.OnServerEvent:connect(function(plr, type, detainee, code)
	if code ~= "PQ8pYaSCNp" then print("Wrong code, "..detainee.Name..". Try again next time.") return end
	local hum	= lib.GetHumanoid(detainee)
	if type == "Detain" then
		print(detained[detainee]) -- this prints nothing!
		if detained[detainee] then print(plr.Name.." tried to detain "..detainee.Name.." but he/she was already detained.") return end -- this doesn't print when someone is detained, and someone else tries to detain them!
		print("Detaining "..detainee.Name)
		detained[detainee] = true
		spawn(function() for i,v in next, detained do
			print(tostring(i).." is detained.")
		end end)
		setCanCollide(detainee, false)
		detainee.Torso.Anchored = true
		hum.JumpPower	= 0
		hum.WalkSpeed	= 0
		connections[1]	= detainee.ChildAdded:connect(function()
			removeTools(detainee)
		end)
		connections[2]	= lib.GetHumanoid(plr.Character).Died:connect(function()
			detained[detainee] = false
		end)
		removeTools(detainee)
		spawn(function()
			while detained[detainee] do
				wait()
				detainee:SetPrimaryPartCFrame(plr.Character:GetPrimaryPartCFrame() * CFrame.new(0, 0, -2.5))
			end
		end)
		detain:FireClient(plr, true)
	elseif type == "Undetain" then
		print("Undetaining "..detainee.Name)
		detainee.Torso.Anchored = false
		hum.JumpPower	= 50
		hum.WalkSpeed	= 16
		setCanCollide(detainee, true)
		detained[detainee] = false
		for i,v in next, connections do v:disconnect() end
		detain:FireClient(plr, false)
	end
end)

LocalScript:

local plr			= game.Players.LocalPlayer
local m				= plr:GetMouse()
local chr			= plr.Character or plr.CharacterAdded:wait()
local tool			= script.Parent
local detain		= tool:WaitForChild("Detain")
local	 code			= "PQ8pYaSCNp"
local detainee	= false
local last

tool.Activated:connect(function()
	if not detainee then
		local detained = game.Players:GetPlayerFromCharacter(m.Target.Parent).Character -- just to make sure it's an actual player, k?
		if detained then
			detain:FireServer("Detain", detained, code)
		end
		last = detained
	elseif detainee then
		detainee	= false
		detain:FireServer("Undetain", last, code)
	end
end)

detain.OnClientEvent:connect(function(bool)
	detainee = bool
end)

This script is suppose to only allow one person to detain a specified player at a time.

Okay, so my problem is that "detained[detainee]" is never set to true (I think?), because when someone is detained and someone else tries to detain them, it never prints "Player tried to detain Player1, but Player1 was already detained".

Anyone know why this debounce isn't working? Probably a stupid question, but I need help.

Most of the problems are on lines 31, and 32.