How to make a tool that can only be picked up by a certain team

Hello everyone, I am trying to create a capture the flag game, and I only want the opposite team to be able to pick up the other teams flag. For example, Red team can pick up the blue teams flag but blue team cant pick up their own flag. I’m not really sure on how to do this as I am fairly new to scripting.

2 Likes

Usually The logic script is on ServerScriptService and you need to use Script (not LocalScript)
You can use the if statement to determine the Player.Team instance property
Like .

-- I dont know what your logic and way is 
-- This is how to check which team Player is in
local Players = game:GetService("Players")
local tool = workspace:WaitForChild("XXX") -- your tool name
-- Then Code Prompt Logic

However, it’s a best practice to look through the API documentation
Tool | Document - Roblox Creator Hub
Lua 5.0 Reference Manual - contents

is your flag just a simple TouchInterest tool or does it use a ClickDetector or some other method?

My flag is just a touch intrest tool

just use BasePart.Touched event connect to get Character’s part and check from Players:GetPlayerFromCharacter()

I tried to make it but it doesnt work, here is the script that i made(sorry for the late response I was on a trip and didn’t have wifi):

local players = game:GetService(“Players”)

local Red_flag = workspace:WaitForChild(“RedFlag”)
local teams = game:GetService(“Teams”)

Red_flag.Touched:connect(function(hit)

local Humanoid = hit.Parent:FindFirstChild("Humanoid")

if hit.Parent == Humanoid then 
	local player = players:GetPlayerFromCharacter("RedFlag")
	
	if Humanoid.Team == teams.Blue and not player:FindFirstChild("Red_flag") then 
		local Flag = game.ServerStorage:FindFirstChild("Red_flag")
		Flag.Parent = player.Backpack
	
	elseif Humanoid.Team == teams.Red then 
		player.Backpack:WaitForChild("Red_flag")
		if player.Backpack:WaitForChild("Red_flag") then 
			player.Backpack:WaitForChild("Red_flag"):Destroy() 
		end
	end
end

end)

1 Like

oops Humanoid does not have the attribute Team, it is in a Player instance in Players and also you can get player’s character from Players:GetPlayerFromCharacter() (You need finding its parent) But as for I know. BasePart.Touched will return a basepart instance and maybe it doesnt hava parent. so replace your code
local Humanoid = hit.Parent:FindFirstChild("Humanoid") with

local hit_parent = hit:FindFirstAncestorWhichIsA("Model")
local Humanoid = hit_parent  and hit_parent:FindFirstChild("Humanoid") or nil


This is a character
And if something else touch that flag then what will happend with hit.Parent :face_with_raised_eyebrow:?

You can do it like so:

tool.Touched:Connect(function(hit)
local hum = hit.Parent:FindFirstChild(“Humanoid”)
if hum then
local char = hum.Parent
local player = char:GetPlayerFromCharacter()
local team = player.Team
if team.Name == “Red” then
local newTool = tool:Clone()
newTool.Parent = player.Backpack
end
end
end)

This should work and im sorry if it doesnt and ill try to help more :slight_smile:

1 Like

I tried this, but it still kept on giving the flag to Red team, even after I changed the if statement to:
if team.Name == “Blue”

I tried this but it still didn’t work.

Here is a video of the problem

Disable the default picked up functionality of the tool, and add a script to the handle of the tool.
Use a part.Touched event and check if it is a player and of the correct team, and if so, parent the tool to their character model.

Put this script in a part that the players touch to get a flag, and change the requiredTeam and givenTool variable as needed

--[[ Variables ]]--
-- Services --
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Teams = game:GetService("Teams")

-- Giver --
local requiredTeam = Teams["team name here"] -- The team that can pick up the flag
local givenTool = ServerStorage["tool name here"]

local function playerHasTool(player : Player) : boolean
	local backpackTool = player.Backpack:FindFirstChild(givenTool.Name)
	if backpackTool ~= nil then
		return true
	end
	
	local characterTool = player.Character:FindFirstChild(givenTool.Name)
	if characterTool ~= nil then
		return true
	end
	
	return false
end

local function onTouched(hitPart : BasePart) : ()
	-- Check for a valid player character
	local player = Players:GetPlayerFromCharacter(hitPart.Parent)
	if player == nil or player.Team ~= requiredTeam then
		return
	end
	
	-- Don't give out a flag if they already have one
	if playerHasTool(player) then
		return
	end
	
	-- Give out the tool
	local tool = givenTool:Clone()
	tool.Parent = player.Backpack
end
script.Parent.Touched:Connect(onTouched)

can you show your code now?
I think it’s the problem of if
But now that it can be picked up, it’s also a step forward
uhh I read your previous code and I recommend you to learn the unified code style and don’t overdesign. There’s a lot of your code that baffles me

local Players = game:GetService("Players")

local RedFlag = workspace:WaitForChild("RedFlag")
local RedFlagName = RedFlag.Name

local Teams = game:GetService("Teams")


local RED_FLAG = 0
local BLUE_FLAG = 1

local function PlayerCanHaveWhichATool(player: Player)
	if player.Team == Teams.Blue then
		return RED_FLAG
	else
		return BLUE_FLAG
	end
end

local function PlayerEquipTool(player: Player, tool: Tool)
	tool.Parent = player.Backpack
end

local function GetPlayerFlag(player: Player, flagName: string)
	local backpack = player.Backpack
	local character = player.Character
	
	local equippedRedFlag = character:FindFirstChild(flagName)
	local unequippedRedFlag = backpack:FindFirstChild(flagName)
	return equippedRedFlag or unequippedRedFlag
end

local function RedFlag_onTouched(hitPart: BasePart)
	local hitPart_Parent = hitPart:FindFirstAncestorWhichIsA("Model")
	local humanoid = hitPart_Parent and hitPart_Parent:FindFirstChild("Humanoid") or nil
	
	if not humanoid then
		return
	end
	
	local player = Players:GetPlayerFromCharacter(hitPart_Parent)
	if PlayerCanHaveWhichATool(player) == RED_FLAG then
		local ThisPlayer_hasRedFlag = GetPlayerFlag(player, RedFlag.Name)
		if ThisPlayer_hasRedFlag then
			ThisPlayer_hasRedFlag:Destroy()
		end
		return
	else	
		if GetPlayerFlag(player, RedFlag.Name) then
			return
		end
		PlayerEquipTool(player, RedFlag)
	end
	
end


RedFlag.Touched:Connect(RedFlag_onTouched)

The bad of your code:

  1. Your goal is to get another Workspace tool in ServerStorage, it’s redundant, you either destroy the Workspace tool and make a copy of the ServerStorage tool, or just use the Workspace tool
  2. Don’t overdo it
  3. Your code logic is not clear enough
  4. Unknown destruction of Team Red player Flag when Team Red player touched
  5. Abusing FindFirstChild and WaitForChild is a bad thing
  6. workspace.Tool This will point to the original Tool, it is a pointer
  7. The original Tool will only be deleted when equipped
  8. The children and parents of the instance tree are pointers because Roblox can only give pointers to instances
  9. RobloxService name according to CamelCase
  10. Sometimes hit is not necessarily a child under the player
  11. Need to check the parent of the hit This will be good for you in future updates Often a lot of errors are caused by the early stages

This worked! Also is there any documentation I can read to get some better understanding of the code?

If there’s anything in particular you’d like me to explain, I can do so

just this function and I am also wondering why did you use colons in the argument and what they do :local function playerHasTool(player : Player) : boolean
local backpackTool = player.Backpack:FindFirstChild(givenTool.Name)
if backpackTool ~= nil then
return true
end

local characterTool = player.Character:FindFirstChild(givenTool.Name)
if characterTool ~= nil then
	return true
end

return false

end

In simple terms, it’s type checking notation. It doesn’t do anything except tell the autocomplete what you’re working with.

local player : Player = ... --// The autocomplete will treat this variable as a player
local playerHumanoid : Humanoid = player.Character.Humanoid --// Ditto, but with humanoids

It’s not something I’d say is necessary to learn, but I like doing it because it saves me some time.
Learn more here

1 Like

If you’re going to critique someone’s code, at least be constructive. None of your bullet points are explained very well, if at all.

Really? Do better.

1 Like