HUDPaint() Traitors can see detectives

Hello.

I’m doing some experiments, with HUDPaint().
I would like to make traitors can see a text “Detective” in the exact position of the detectives, simple not?

I made something like this:



hook.Add( "HUDPaint", "DetectiveText", function()
	for _, ply in pairs( player.GetAll() ) do
		if ply:IsDetective() then
			local detectivepos = ply:GetPos():ToScreen()
		end
		if ply:IsTraitor() then
			draw.SimpleText( "Detective", "Trebuchet24", detectivepos.x, detectivepos.y, Color( 255, 0, 0, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM )
		end
	end
end )


But the console give me this error: attempt to index global ‘detectivepos’ (a nil value)

I tried to make something like this:



local detectivepos
hook.Add( "HUDPaint", "DetectiveText", function()
	for _, ply in pairs( player.GetAll() ) do
		if ply:IsDetective() then
			detectivepos = ply:GetPos():ToScreen()
		end
		if ply:IsTraitor() then
			draw.SimpleText( "Detective", "Trebuchet24", detectivepos.x, detectivepos.y, Color( 255, 0, 0, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM )
		end
	end
end )


But it doesn’t work!
Some help?

Thank you!

Anyone?

What you’re doing is:

  1. Loop through all the players in the game
  2. Check if each player is a detective, if so, update detectivepos with their position
  3. Check if each player is a traitor, and for each traitor, draw text at the detective’s position for every player

The problems with this are:

  1. If there are no detectives, detectivepos will be nil and cause an error
  2. You are (if detectivepos isn’t nil) drawing text on every player’s screen for each traitor in the game

Try something like this instead


hook.Add( "HUDPaint", "DetectiveText", function()
	
	if LocalPlayer():IsTraitor() == true then //If the client is a traitor then
		
		for _, ply in pairs( player.GetAll() ) do //For each player in the game do
			
			if ply:IsDetective() == true then //If this player is a detective then
				
				local detectivepos = ply:GetPos():ToScreen() //Create a value with their position
				draw.SimpleText( "Detective", "Trebuchet24", detectivepos.x, detectivepos.y, Color( 255, 0, 0, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM ) //Draw text at the detective's position
				
			end
			
		end
		
	end
	
end )

Yes I know, that If there are no detectives, detectivepos will be nil and cause an error, in fact the real code is this:



hook.Add( "HUDPaint", "DetectiveText", function()
	for _, ply in pairs( player.GetAll() ) do
local therearedetectives = false
		if ply:IsDetective() then
			local detectivepos = ply:GetPos():ToScreen()
                        therearedetectives = true
		end
		if ply:IsTraitor() and therearedetectives then
			draw.SimpleText( "Detective", "Trebuchet24", detectivepos.x, detectivepos.y, Color( 255, 0, 0, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM )
		end
	end
end )


I have a question, your code says:


	
		if ply:IsDetective() == true then //If this player is a detective then
				
				local detectivepos = ply:GetPos():ToScreen() //Create a value with their position
				draw.SimpleText( "Detective", "Trebuchet24", detectivepos.x, detectivepos.y, Color( 255, 0, 0, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM ) //Draw text at the detective's position
				
			end


So if a player is detective then copy his position and draw a simple text, so the text will be visible also at detectives, not?

[editline]24th August 2016[/editline]

I tried it, and detective see the traitors!

LocalPlayer() returns the client, the player you’re running the clientside code on.


if LocalPlayer():IsTraitor() == true then

This makes sure the player you’re trying to draw the text for is a traitor.


for _, ply in pairs( player.GetAll() ) do

This loops through all players in the game, running the code below for each of them, until it reaches “end”, so here it checks for detectives, and since there is an IsTraitor() check in the beginning, it will only run any of this if the player is a traitor.

I’m not sure how this code could in anyway cause detectives to see traitors, when I tested it it worked as intended.

Traitor status of all players is only known server side, unless you are a traitor yourself.
So you will have to do some server side coding as well to make this work.