Code issues - Preventing Teamkill

Hello! I need a hand with my script. I’m trying to implement a restriction to prevent team kill, but I’ve been struggling, and I’m not sure what I’m doing wrong. :frowning:

Here I’ll show you my module script and my server script. I need players from team1 not to be able to attack their own team. Any ideas on how to do it or could you lend me a hand? I would appreciate it a lot.

Module-Script:

local TeamsModule = {}

function TeamsModule.new()
	local team1 = {
		name = "Blue Team",
		players = {},
		maxPlayers = 3
	}

	local team2 = {
		name = "Red Team",
		players = {},
		maxPlayers = 3
	}

	return team1, team2
end

return TeamsModule

server-script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TeamsModule = require(ReplicatedStorage.TeamsModuleScript)
local gunFireEvent = script.Parent:WaitForChild("gunFire")

local team1, team2 = TeamsModule.new()

gunFireEvent.OnServerEvent:Connect(function(player, target, hitPosition)
	print("Server: Received gunFireEvent from " .. player.Name .. " targeting " .. target.Name .. " at " .. tostring(hitPosition))

	-- Get the team of the player and the target
	local playerTeam = nil
	local targetTeam = nil

	-- Check if the player is in team1
	if table.find(team1.players, player) then
		playerTeam = team1
		targetTeam = team2
		-- Check if the player is in team2
	elseif table.find(team2.players, player) then
		playerTeam = team2
		targetTeam = team1
	end

	-- Check if the player and target are in different teams
	if playerTeam and targetTeam and playerTeam ~= targetTeam then
		print("Server: Player " .. player.Name .. " can damage enemy " .. target.Name)

		-- Rest of the code to cause damage to the target
		local damage = 10
		local humanoid = target:FindFirstChildOfClass("Humanoid")

		if humanoid then
			humanoid:TakeDamage(damage)
			print("Server: Dealt " .. damage .. " damage to " .. target.Name)
		else
			print("Server: Target " .. target.Name .. " does not have a Humanoid.")
		end
	else
		print("Server: Player " .. player.Name .. " cannot damage teammate " .. target.Name)
	end
end)
1 Like

When the players are added, are you inserting the player instance to the team table?

1 Like

yes, using player added and player removing (added to add players to team and removing to remove players from teams)

-- Server Script

local TeamsModule = require(game.ReplicatedStorage.TeamsModuleScript)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local playerAddedEvent = ReplicatedStorage:WaitForChild("PlayerAddedEvent")

-- Get the list of teams created in the module
local team1, team2 = TeamsModule.new()

-- Set the player limits for each team
local maxPlayersTeam1 = team1.maxPlayers
local maxPlayersTeam2 = team2.maxPlayers

-- Function to assign randomly to a team
local function assignToRandomTeam(player)
	local randomNumber = math.random(1, 2) -- Generate a random number between 1 and 2

	-- Check the random number and assign the player to the appropriate team
	if randomNumber == 1 then
		if #team1.players < maxPlayersTeam1 then
			table.insert(team1.players, player)
			print(player.Name .. " added to " .. team1.name .. " team. Players in team: " .. #team1.players)
			return team1
		else
			print(player.Name .. " not added to " .. team1.name .. " team. Team is full.")
			return team2
		end
	else
		if #team2.players < maxPlayersTeam2 then
			table.insert(team2.players, player)
			print(player.Name .. " added to " .. team2.name .. " team. Players in team: " .. #team2.players)
			return team2
		else
			print(player.Name .. " not added to " .. team2.name .. " team. Team is full.")
			return team1
		end
	end
end

-- Function to remove a player from the team
local function removePlayerFromTeam(player)
	-- Loop through Team 1's player list and remove the player
	for i, teamPlayer in ipairs(team1.players) do
		if teamPlayer == player then
			table.remove(team1.players, i)
			break
		end
	end

	-- Loop through Team 2's player list and remove the player
	for i, teamPlayer in ipairs(team2.players) do
		if teamPlayer == player then
			table.remove(team2.players, i)
			break
		end
	end
end

-- Example of usage in the PlayerAdded event
game.Players.PlayerAdded:Connect(function(player)
	-- Assign the player to a random team
	local assignedTeam = assignToRandomTeam(player)
	print(player.Name .. " assigned to " .. assignedTeam.name)

	-- Fire the RemoteEvent to update the client
	playerAddedEvent:FireClient(player, #team1.players, #team2.players)
end)

-- Example of usage in the PlayerRemoving event
game.Players.PlayerRemoving:Connect(function(player)
	-- Remove the player from the team's player list
	removePlayerFromTeam(player)
	print(player.Name .. " is leaving the game.")
end)
1 Like

something like this? i tried and still dont work:

-- Server Script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TeamsModule = require(ReplicatedStorage.TeamsModuleScript)
local gunFireEvent = script.Parent:WaitForChild("gunFire")

local team1, team2 = TeamsModule.new()

gunFireEvent.OnServerEvent:Connect(function(player, target, hitPosition)
    print("Server: Received gunFireEvent from " .. player.Name .. " targeting " .. target.Name .. " at " .. tostring(hitPosition))

    -- Get the team of the player and the target
    local playerTeam = nil
    local targetTeam = nil

    -- Check if the player is in team1
    for _, teamPlayer in pairs(team1.players) do
        if teamPlayer == player then
            playerTeam = team1
            break
        end
    end

    -- Check if the player is in team2
    for _, teamPlayer in pairs(team2.players) do
        if teamPlayer == player then
            playerTeam = team2
            break
        end
    end

    -- Check if the target is in team1
    for _, teamPlayer in pairs(team1.players) do
        if teamPlayer == target then
            targetTeam = team1
            break
        end
    end

    -- Check if the target is in team2
    for _, teamPlayer in pairs(team2.players) do
        if teamPlayer == target then
            targetTeam = team2
            break
        end
    end

    -- Check if both player and target are in teams and they are in different teams
    if playerTeam and targetTeam and playerTeam ~= targetTeam then
        print("Server: Player " .. player.Name .. " can damage enemy " .. target.Name)

        -- Rest of the code to cause damage to the target
        local damage = 10
        local humanoid = target:FindFirstChildOfClass("Humanoid")

        if humanoid then
            humanoid:TakeDamage(damage)
            print("Server: Dealt " .. damage .. " damage to " .. target.Name)
        else
            print("Server: Target " .. target.Name .. " does not have a Humanoid.")
        end
    else
        print("Server: Player " .. player.Name .. " cannot damage teammate " .. target.Name)
    end
end)
1 Like

I just realized that this does not update the list of players in each team and that is why my script does not work and the list of players is empty, what can I do to solve that?

script adding random team

local TeamsModule = require(game.ReplicatedStorage.TeamsModuleScript)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local playerAddedEvent = ReplicatedStorage:WaitForChild("PlayerAddedEvent")

-- Get the list of teams created in the module
local team1, team2 = TeamsModule.new()

-- Set the player limits for each team
local maxPlayersTeam1 = team1.maxPlayers
local maxPlayersTeam2 = team2.maxPlayers

-- Function to assign randomly to a team
local function assignToRandomTeam(player)
	local randomNumber = math.random(1, 2) -- Generate a random number between 1 and 2

	-- Check the random number and assign the player to the appropriate team
	if randomNumber == 1 then
		if #team1.players < maxPlayersTeam1 then
			table.insert(team1.players, player)
			print(player.Name .. " added to " .. team1.name .. " team. Players in team: " .. #team1.players)
			return team1
		else
			print(player.Name .. " not added to " .. team1.name .. " team. Team is full.")
			return team2
		end
	else
		if #team2.players < maxPlayersTeam2 then
			table.insert(team2.players, player)
			print(player.Name .. " added to " .. team2.name .. " team. Players in team: " .. #team2.players)
			return team2
		else
			print(player.Name .. " not added to " .. team2.name .. " team. Team is full.")
			return team1
		end
	end
end

-- Function to remove a player from the team
local function removePlayerFromTeam(player)
	-- Loop through Team 1's player list and remove the player
	for i, teamPlayer in ipairs(team1.players) do
		if teamPlayer == player then
			table.remove(team1.players, i)
			break
		end
	end

	-- Loop through Team 2's player list and remove the player
	for i, teamPlayer in ipairs(team2.players) do
		if teamPlayer == player then
			table.remove(team2.players, i)
			break
		end
	end
end

-- Example of usage in the PlayerAdded event
game.Players.PlayerAdded:Connect(function(player)
	-- Assign the player to a random team
	local assignedTeam = assignToRandomTeam(player)
	print(player.Name .. " assigned to " .. assignedTeam.name)

	-- Fire the RemoteEvent to update the client
	playerAddedEvent:FireClient(player, #team1.players, #team2.players)
end)

-- Example of usage in the PlayerRemoving event
game.Players.PlayerRemoving:Connect(function(player)
	-- Remove the player from the team's player list
	removePlayerFromTeam(player)
	print(player.Name .. " is leaving the game.")
end)

module script:

local TeamsModule = {}

function TeamsModule.new()
	local team1 = {
		name = "Blue Team",
		players = {},
		maxPlayers = 3
	}

	local team2 = {
		name = "Red Team",
		players = {},
		maxPlayers = 3
	}

	return team1, team2
end

return TeamsModule
1 Like

Why dont you make instance teams inside the TeamService?

1 Like

You’re overcomplicating it for yourself my man.
All you need to do is in your if statement under the gunFireEvent function is
(first make sure target is a character)

local targetPlayer = game.Players:GetPlayerFromCharacter(target.Parent)

if targetPlayer and  targetPlayer:IsA("Player") then
	if player.Team.TeamColor ~= targetPlayer.Team.TeamColor then
		--- Injure TargetPlayer
	else 
		return null
	end
end

As programmers, we overcomplicate things, but from what it looks like you need to slow down!
There is no need for that teams module, there is a Built in TeamService for a reason, it does the exact same thing.

Sometimes it’s just best to slow down.
@PipeSader

2 Likes

Unless there is a good reason why your not using TeamService this module is just overcomplicating it for you, there isn’t a need to assign server memory to a completely new class that does the same thing as a built-in class which is probably more optimized than this Team module.

2 Likes

Hmm you are absolutely right, the truth is I never thought about doing it with that, I think it was my lack of practice, thanks for mentioning it, look I tried to do this but it doesn’t work correctly

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TeamsService = game:GetService("Teams")  -- Corregir el nombre del servicio
local gunFireEvent = script.Parent:WaitForChild("gunFire")

-- Get teams
local blueTeam = TeamsService:WaitForChild("Blue Team")
local redTeam = TeamsService:WaitForChild("Red Team")

-- Function to check if two players are on different teams
local function arePlayersOnDifferentTeams(player1, player2)
    return player1.Team ~= player2.Team
end

-- Connect the gunFireEvent
gunFireEvent.OnServerEvent:Connect(function(player, target, hitPosition)
    print("Server: Received gunFireEvent from " .. player.Name .. " targeting " .. target.Name .. " at " .. tostring(hitPosition))

    -- Check if the players are on different teams
    if arePlayersOnDifferentTeams(player, target) then
        -- Apply damage logic here (replace this with your actual damage logic)
        local damage = 10
        target:TakeDamage(damage)
        print(target.Name .. " took " .. damage .. " damage from " .. player.Name)
    else
        print("Cannot damage teammate.")
    end
end)

This is not true, table.find finds an element in an array based off of a value.

table.find takes an array as the first argument, a value (to search for as the second argument), and an optional starting index as the third argument (if nil this defaults to 1). The function returns an index.

One way to express = table.find(Array: table, ValueToSearchFor: any, StartingIndex: number?)

2 Likes

Yea, you can’t do player1.Team ~= player2.Team because they are instances which can’t be compared by an if statement. You have to compare the Team.Name or Team.TeamColor.

1 Like

Well I’m glad I could help you figure out the issue, it doesn’t really seem like a practice issue, more just remember to slow down and review your code when you are programming, experience can help because usually once you know that you can’t compare Instances when comparing the player’s team, but you have to instead compare their properties. They are the same instance type so it will not work the way you want it to.

1 Like

Thank you very much for your advice, I think I’m on the right track, I tried to do this in test with 3 players from Roblox studio and it tells me an error

21:18:07.967 Team is not a valid member of Model “Workspace.Player3” - Servidor - Server-Side:11

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TeamsService = game:GetService("Teams")
local gunFireEvent = script.Parent:WaitForChild("gunFire")

-- Get teams
local blueTeam = TeamsService:WaitForChild("Blue Team")
local redTeam = TeamsService:WaitForChild("Red Team")

-- Function to check if two players are on different teams
local function arePlayersOnDifferentTeams(player1, player2)
	return player1.Team.Name ~= player2.Team.Name
end

-- Connect the gunFireEvent
gunFireEvent.OnServerEvent:Connect(function(player, target, hitPosition)
	print("Server: Received gunFireEvent from " .. player.Name .. " targeting " .. tostring(target) .. " at " .. tostring(hitPosition))

	-- Check if target is a player
	if target:IsA("Player") then
		-- Check if the players are on different teams
		if arePlayersOnDifferentTeams(player, target) then
			-- Apply damage logic here (replace this with your actual damage logic)
			local damage = 10
			target:TakeDamage(damage)
			print(target.Name .. " took " .. damage .. " damage from " .. player.Name)
		else
			print("Cannot damage teammate.")
		end
	else
		print("Target is not a player.")
	end
end)

That’s because you defined the target as the player, target is the 2nd player’s character, not the 2nd player’s actual player, so you have to define the plr.

Try:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TeamsService = game:GetService("Teams")
local gunFireEvent = script.Parent:WaitForChild("gunFire")

-- Get teams
local blueTeam = TeamsService:WaitForChild("Blue Team")
local redTeam = TeamsService:WaitForChild("Red Team")

-- Function to check if two players are on different teams
local function arePlayersOnDifferentTeams(player1, player2)
	return player1.Team.Name ~= player2.Team.Name
end

-- Connect the gunFireEvent
gunFireEvent.OnServerEvent:Connect(function(player, target, hitPosition)
	print("Server: Received gunFireEvent from " .. player.Name .. " targeting " .. tostring(target) .. " at " .. tostring(hitPosition))
	local targetPlayer = game.Players:GetPlayerFromCharacter(target)
	-- Check if target is a player
	if targetPlayer:IsA("Player") then
		-- Check if the players are on different teams
		if arePlayersOnDifferentTeams(player, targetPlayer) then
			-- Apply damage logic here (replace this with your actual damage logic)
			local damage = 10
			target:FindFirstChildOfClass("Humanoid"):TakeDamage(damage)
			print(target.Name .. " took " .. damage .. " damage from " .. player.Name)
		else
			print("Cannot damage teammate.")
		end
	else
		print("Target is not a player.")
	end
end)
2 Likes

Oh thank you so much finally! Sorry for disturbing and thank you all very much for your collaboration! :smiley: I hope to improve over time and be better at programming

1 Like

No worries man, I really do enjoy helping others out no disturbance was caused lel. Just keep on trying, programming can be more error than trial and error and vise versa, but keep on going!

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.