Bodygroup set problem

hook.Add("PlayerSpawn", "CheckFullStats", function(ply)

	ply:SetTeam(TEAM_CITIZEN)
	if (table.HasValue(A, ply:SteamID())) then
		ply:SetTeam(BB)
	elseif (table.HasValue(B, ply:SteamID())) then
		ply:SetTeam(CC)
	elseif (table.HasValue(C, ply:SteamID())) then
		ply:SetTeam(DD)
	elseif (table.HasValue(D, ply:SteamID())) then
		ply:SetTeam(EE)
	end

end)


function setrobe(player)
	local robe = player:FindBodygroupByName("ROBES")

	if (robe == 4) then
		player:SetBodygroup(4, 1)
		
	else
		player:SetBodygroup(7,1)
		
	end

end

function playerReset( ply )
	
	ply:SetNWInt("posReset", ply:GetPos())
	ply:Spawn()
	ply:SetPos(ply:GetNWInt("posReset"))
	setrobe(ply)

end

hook.Add("PlayerSay", "gdfgd", function(sender,text,teamChat)

	if (string.lower(text) == "/reset") then

		playerReset(sender)

	end

end)

I spend many time but i still didn’t get why its not work. Can you please help me?

What doesn’t work? That’s pretty unclear… Reading quickly, your code has two big mistakes in my opinion:

You invoke the player parameter here, however this can be confusing as player is a built-in library of Garry’s Mod and thus can cause a conflict under certain conditions.

Also, here you call a function to store the last position of the player, however this function only stores unsigned integers. The position of a player is commonly retrieved/defined as a vector (expressed in three components: X, Y, Z), the most appropriate function would be PLAYER.Set/GetNWVector. I would like to point out that this function allows you to retrieve this value on the client side because it is automatically networked to all players on the server. If you are just going to use it in a server side context, just put it in a local variable.

One last thing that is not really a mistake but more of an optimization problem. You use the table.HasValue function which iterates through pairs to find a specific value (o(n) complexity). This method is far from being efficient. If you have a table like :

local a = {
	"value1",
	"value2",
	"value3"
}

I suggest you modify it like this:

local a = {
	["value1"] = true,
	["value2"] = true,
	["value3"] = true
}

This will allow you to stop using this function and just do :

-- code...
if A[ ply:SteamID() ] then
-- code...

After all these explanations, here is the revised code:

hook.Add( "PlayerSpawn", "CheckFullStats", function( ply )
	ply:SetTeam( TEAM_CITIZEN )

	if A[ ply:SteamID() ] then
		ply:SetTeam( BB )
	elseif B[ ply:SteamID() ] then
		ply:SetTeam( CC )
	elseif C[ ply:SteamID() ] then
		ply:SetTeam( DD )
	elseif D[ ply:SteamID() ] then
		ply:SetTeam( EE )
	end
end )

local function setrobe( ply )
	local robe = ply:FindBodygroupByName( "ROBES" )

	if robe == 4 then
		ply:SetBodygroup( 4, 1 )
	else
		ply:SetBodygroup( 7, 1 )
	end
end

local function playerReset( ply )
	local position = ply:GetPos()

	ply:Spawn()
	ply:SetPos( position )

	setrobe( ply )
end

hook.Add( "PlayerSay", "gdfgd", function( sender, text, teamChat )
	if string.lower( text ) == "/reset" then
		playerReset( sender )
	end
end )
1 Like

Thanks for your help but…
Setting bodygroups on the model doesn’t work even with your fixes.

Do you use this script on models from the Workshop? (If yes, can I have the link to test it?)

Yes. Steam Workshop::HogwartsRP - Students Rework

I just tested and there is no problem. Here is my files:

-- Server file
hook.Add( "PlayerSpawn", "CheckFullStats", function( ply )
    ply:SetTeam( TEAM_POLICE )

    -- if A[ ply:SteamID() ] then
    --  ply:SetTeam( BB )
    -- elseif B[ ply:SteamID() ] then
    --  ply:SetTeam( CC )
    -- elseif C[ ply:SteamID() ] then
    --  ply:SetTeam( DD )
    -- elseif D[ ply:SteamID() ] then
    --  ply:SetTeam( EE )
    -- end
end )

local function setrobe( ply )
    local robe = ply:FindBodygroupByName( "ROBES" )

    if robe == 4 then
        ply:SetBodygroup( 4, 1 )
    else
        ply:SetBodygroup( 7, 1 )
    end
end

local function playerReset( ply )
    local position = ply:GetPos()
    ply:Spawn()
    ply:SetPos( position )

    setrobe( ply )
end

hook.Add( "PlayerSay", "gdfgd", function( sender, text, teamChat )
    if string.lower( text ) == "/reset" then
        playerReset( sender )
    end
end )
-- DarkRP job
TEAM_POLICE = DarkRP.createJob("Base", {
    color = Color(0, 0, 153, 253),
    model = {
        "models/konnie/students/male_hufflepuff.mdl",
    },
    description = "",
    weapons = {},
    command = "base",
    max = 0,
    salary = 3,
    admin = 0,
    vote = false,
    hasLicense = false,
    candemote = false,
})

My game has almost no addons and I tested this on a dedicated server on DarkRP gamemode. Your script doesn’t work if the model doesn’t have a bodygroup with the name “Robes” but in any case, you define the bodygroup after the model so there shouldn’t be any problem.

In my jobs.lua a few models to job.

TEAM_NAME = DarkRP.createJob("name", {
    color = Color(125, 0, 0, 255),
    model = {
        "models/konnie/students/female_gryffindor.mdl",
        "models/konnie/students/male_gryffindor.mdl"
    },
    description = [[]],
    weapons = {"name_weapon", "name_weapon"},
    command = "Good",
    max = 1, -- at most 70% of the players can have this job. Set to a whole number to set an absolute limit.
    salary = 0,
    admin = 0,
    vote = false,
    hasLicense = false,
})
TEAM_NAME = DarkRP.createJob("name", {
    color = Color(125, 125, 0, 255),
    model = {
        "models/konnie/students/female_hufflepuff.mdl",
        "models/konnie/students/male_hufflepuff.mdl"
    },
    description = [[]],
    weapons = {"name_weapon", "name_weapon"},
    command = "Good1",
    max = 1, -- at most 70% of the players can have this job. Set to a whole number to set an absolute limit.
    salary = 0,
    admin = 0,
    vote = false,
    hasLicense = false,
})
TEAM_NAME = DarkRP.createJob("name", {
    color = Color(0, 0, 125, 255),
    model = {
        "models/konnie/students/female_ravenclaw.mdl",
        "models/konnie/students/male_ravenclaw.mdl"
    },
    description = [[]],
    weapons = {"name_weapon", "name_weapon"},
    command = "Good2",
    max = 1, -- at most 70% of the players can have this job. Set to a whole number to set an absolute limit.
    salary = 0,
    admin = 0,
    vote = false,
    hasLicense = false,
})
TEAM_NAME = DarkRP.createJob("name", {
    color = Color(0, 125, 0, 255),
    model = {
        "models/konnie/students/female_slytherin.mdl",
        "models/konnie/students/male_slytherin.mdl"
    },
    description = [[]],
    weapons = {"name_weapon", "name_weapon"},
    command = "Good3",
    max = 1, -- at most 70% of the players can have this job. Set to a whole number to set an absolute limit.
    salary = 0,
    admin = 0,
    vote = false,
    hasLicense = false,
})

I tested again with male/female variants and with various factions but I really have no problem. Are you getting an error or something? By the way, what are the tables named “A”, “B”, “C”, etc. listed in the server script?

Im dont get any errors.
Tables:

	A = util.JSONToTable( file.Read( "pathtofile1.txt") )
	B = util.JSONToTable( file.Read( "pathtofile2.txt") )
	C = util.JSONToTable( file.Read( "pathtofile3.txt") )
	D = util.JSONToTable( file.Read( "pathtofile4.txt") )

What about the BB, CC, etc. variables in the PlayerSpawn hook?

It’s team names

Team names of what? The identifiers? Because when you’re doing DarkRP faction creation, it’s best to name TEAM_<identifier> and not just BB or whatever you want. It’s just a matter of standard even though the DarkRP.createJob function returns a number in all cases. However, the BB or CC job is not included in your job file you posted earlier so I doubt this part will work.

The name of the teams is correct there (TEAM _…), I just censored it like BB, CC. Set team to player when he spawns working, only part of setbodygroups dont working, i dont know why.

Honestly, without full source code, I could give you a solution. But all I know is that the script itself technically works. So I think you’ll have to look a little bit on your side.

Sorry.
Server:

hook.Add("PlayerSpawn", "CheckFullStats", function(ply)

	Name1 = util.JSONToTable( file.Read( "ceil-choixpo/Name.txt") )
	Name2 = util.JSONToTable( file.Read( "ceil-choixpo/Name2.txt") )
	Name3 = util.JSONToTable( file.Read( "ceil-choixpo/Name3.txt") )
	Name4 = util.JSONToTable( file.Read( "ceil-choixpo/Name4.txt") )	

	ply:SetTeam(TEAM_CITIZEN)
	if (table.HasValue(Name1, ply:SteamID())) then
		ply:SetTeam(TEAM_ABC)
	elseif (table.HasValue(Name2, ply:SteamID())) then
		ply:SetTeam(TEAM_ABCD)
	elseif (table.HasValue(Name3, ply:SteamID())) then
		ply:SetTeam(TEAM_ABCDE)
	elseif (table.HasValue(Name4, ply:SteamID())) then
		ply:SetTeam(TEAM_ABCDEF)
	end



end)

local function setrobe( ply )
	local robe = ply:FindBodygroupByName( "ROBES" )

	if robe == 4 then
		ply:SetBodygroup( 4, 1 )
	else
		ply:SetBodygroup( 7, 1 )
	end
end

local function playerReset( ply )
	local position = ply:GetPos()

	ply:Spawn()
	ply:SetPos( position )

	setrobe( ply )
end


hook.Add("PlayerSay", "gdfgd", function(sender,text,teamChat)

	if (string.lower(text) == "/reset") then

		playerReset(sender)

	end

end)

Jobs:

GAMEMODE.DefaultTeam = TEAM_CITIZEN

TEAM_ABC = DarkRP.createJob("ABCname", {
    color = Color(125, 0, 0, 255),
    model = {
        "models/konnie/students/female_gryffindor.mdl",
        "models/konnie/students/male_gryffindor.mdl"
    },
    description = [[]],
    weapons = {"re_hands", "weapon_hpwr_stick"},
    command = "Good",
    max = 1, -- at most 70% of the players can have this job. Set to a whole number to set an absolute limit.
    salary = 0,
    admin = 0,
    vote = false,
    hasLicense = false,
})
TEAM_ABCD = DarkRP.createJob("ABCDname", {
    color = Color(125, 125, 0, 255),
    model = {
        "models/konnie/students/female_hufflepuff.mdl",
        "models/konnie/students/male_hufflepuff.mdl"
    },
    description = [[]],
    weapons = {"re_hands", "weapon_hpwr_stick"},
    command = "Good1",
    max = 1, -- at most 70% of the players can have this job. Set to a whole number to set an absolute limit.
    salary = 0,
    admin = 0,
    vote = false,
    hasLicense = false,
})
TEAM_ABCDE = DarkRP.createJob("ABCDEname", {
    color = Color(0, 0, 125, 255),
    model = {
        "models/konnie/students/female_ravenclaw.mdl",
        "models/konnie/students/male_ravenclaw.mdl"
    },
    description = [[]],
    weapons = {"re_hands", "weapon_hpwr_stick"},
    command = "Good2",
    max = 1, -- at most 70% of the players can have this job. Set to a whole number to set an absolute limit.
    salary = 0,
    admin = 0,
    vote = false,
    hasLicense = false,
})
TEAM_ABCDEF = DarkRP.createJob("ABCDEFname", {
    color = Color(0, 125, 0, 255),
    model = {
        "models/konnie/students/female_slytherin.mdl",
        "models/konnie/students/male_slytherin.mdl"
    },
    description = [[]],
    weapons = {"re_hands", "weapon_hpwr_stick"},
    command = "Good3",
    max = 1, -- at most 70% of the players can have this job. Set to a whole number to set an absolute limit.
    salary = 0,
    admin = 0,
    vote = false,
    hasLicense = false,
})

When you do the “/reset” command, in which job are you assigned? Because if you are assigned as a citizen, this job obviously doesn’t have the model which has the bodygroup you want.

It doesn’t work in every job. In TEAM_CITIZEN, TEAM_ABC ,TEAM_ABCD ,TEAM_ABCDE ,TEAM_ABCDEF .

By creating a file Name.txt in a folder ceil-choixpo (as indicated in the code) and placing my SteamID (in JSON format), everything works perfectly. I tested with all four jobs and using exactly the same code you put above. I believe this is a problem on your end.

When i was in thirdperson and use /reset, i view how playermodel change to alternative (male/female) with a robe and after set playermodel without robe.

Unfortunately, I really don’t see where the problem could come from. I tested without any addon installed and using Sandbox gamemode to be sure but I have no problem. So if anyone else reading this topic has an idea, go ahead.