Jump to content

onClientPlayerVoiceStart


Recommended Posts

Made a label appear with a player's nickname who say in voice chat.

But if you use such code. it will be bad when they talk a lot of players.

How can I make sure that when several people speak at the same time they create several lines with their names?

vv = guiCreateLabel(17,170,170,30,"",false)
guiSetVisible(vv,false)
addEventHandler ( "onClientPlayerVoiceStart", root,
	function()
		local name = getPlayerName(getLocalPlayer())
		local p_id = getElementData ( source, "ID" )
		voicePlayers[source] = true
		guiSetText(vv,"Talk: "..name.." ["..p_id.."]")
		guiSetFont(vv,myfont)
		guiSetVisible(vv,true)
	end
)

addEventHandler ( "onClientPlayerVoiceStop", root,
	function()
		voicePlayers[source] = nil
		guiSetVisible(vv,false)
	end
)

66v1vzOfuzg.jpg

In the screenshot, I marked the numbers. This, for example, if 4 players are talking at the same time

Link to comment

Try this:

local playersUsingMic = {}
local x, y = guiGetScreenSize ( )
local sx, sy = 1600, 900

function onStartVoiceChat()
	local p_id = getElementData (source, "ID") or "0"
	table.insert(playersUsingMic, {source, p_id})
end
addEventHandler("onClientPlayerVoiceStart", root, onStartVoiceChat)

function onStopVoiceChat()
	for i, v in ipairs(playersUsingMic) do
		if (v[1] == source) then
			table.remove(playersUsingMic, i)
		end
	end
end
addEventHandler("onClientPlayerVoiceStop", root, onStopVoiceChat)

function drawText()
	if (#playersUsingMic > 0) then
		for i, v in ipairs(playersUsingMic) do
			dxDrawText("Talk: "..getPlayerName(v[1]).." ["..v[2].."]", x * (27/sx), i*30 + y * (341/sy), x * (294/sx), i*30 + y * (376/sy), tocolor(255, 255, 255, 255), 1.00, "default-bold", "left", "top", false, false, false, false, false)
		end
	end
end
addEventHandler("onClientRender", root, drawText)

 

Edited by HassoN
  • Like 1
Link to comment
1 hour ago, HassoN said:

Try this:


local playersUsingMic = {}
local x, y = guiGetScreenSize ( )
local sx, sy = 1600, 900

function onStartVoiceChat()
	local p_id = getElementData (source, "ID") or "0"
	table.insert(playersUsingMic, {source, p_id})
end
addEventHandler("onClientPlayerVoiceStart", root, onStartVoiceChat)

function onStopVoiceChat()
	for i, v in ipairs(playersUsingMic) do
		if (v[1] == source) then
			table.remove(playersUsingMic, i)
		end
	end
end
addEventHandler("onClientPlayerVoiceStop", root, onStopVoiceChat)

function drawText()
	if (#playersUsingMic > 0) then
		for i, v in ipairs(playersUsingMic) do
			dxDrawText("Talk: "..getPlayerName(v[1]).." ["..v[2].."]", x * (27/sx), i*30 + y * (341/sy), x * (294/sx), i*30 + y * (376/sy), tocolor(255, 255, 255, 255), 1.00, "default-bold", "left", "top", false, false, false, false, false)
		end
	end
end
addEventHandler("onClientRender", root, drawText)

 

It works like I wanted, BUT if 1 player presses the microphone 2 times, or will press and press several times, there will be such a problem

qMVEtCM5-hE.jpg

and if you let go of the microphone button, the upper inscription will remain, and the lower one will disappear

How to fix it? For one player, the inscription must be one

Link to comment
1 hora atrás, slapz0r disse:
  1.  
  2. locais playersUsingMic={}
  3. local x,y= guiGetScreenSize ()
  4. sx local , sy = 1600 , 900
  5.  
  6. function onStartVoiceChat ()
  7. p_id local = getElementData ( origem , "ID" ) ou "0"
  8. mesa . insert (playersUsingMic,{source,p_id})
  9. fim
  10. addEventHandler (" onClientPlayerVoiceStart ",root,onStartVoiceChat)
  11.  
  12. function onStopVoiceChat ()
  13. para eu , v em ipairs ( playersUsingMic ) fazer
  14. se ( v [ 1 ] == fonte ) então
  15. mesa . remove (playersUsingMic,i)
  16. fim
  17. fim
  18. fim
  19. addEventHandler (" onClientPlayerVoiceStop ",root,onStopVoiceChat)
  20.  
  21. function drawText ()
  22. if (# playersUsingMic > 0 ), então
  23. para eu , v em ipairs ( playersUsingMic ) fazer
  24. dxDrawText ("Talk:".. getPlayerName (["..v[1] .."] ".." ["..v[2] .."] ",x*(27/sx),i*30+y*(341/sy),x*(294/sx),i*30+y*(376/sy), tocolor( 255 , 255 , 255 , 255 ), 1,00 , "default-bold" , "esquerda" , "top" , falso , falso , falso , falso , falso )
  25. fim
  26. fim
  27. fim
  28. addEventHandler (" onClientRender ",root,drawText)



 

Edited by MrShadows
Estava faltando algo
Link to comment
4 minutes ago, MrShadows said:

 

dxDrawText ("Talk:".. getPlayerName (["..v[1] .."]" .."["..v[2] .."]",x*(27/sx),i*30+y*(341/sy),x*(294/sx),i*30+y*(376/sy), tocolor ( 255 , 255 , 255 , 255 ), 1,00 , "default-bold" , "esquerda" , "top" , falso , falso , falso , falso , falso )

What do you have with a line?!

Link to comment
9 hours ago, slapz0r said:

It works like I wanted, BUT if 1 player presses the microphone 2 times, or will press and press several times, there will be such a problem

qMVEtCM5-hE.jpg

and if you let go of the microphone button, the upper inscription will remain, and the lower one will disappear

How to fix it? For one player, the inscription must be one

up

Link to comment
9 hours ago, slapz0r said:

It works like I wanted, BUT if 1 player presses the microphone 2 times, or will press and press several times, there will be such a problem

qMVEtCM5-hE.jpg

and if you let go of the microphone button, the upper inscription will remain, and the lower one will disappear

How to fix it? For one player, the inscription must be one

Sorry for late response, I was sleeping. ?

local playersUsingMic = {}
local x, y = guiGetScreenSize ( )
local sx, sy = 1600, 900

function onStartVoiceChat()
	local myIndex = getMyValue(source)
	if (not myIndex or not playersUsingMic[myIndex]) then
		local p_id = getElementData (source, "ID") or "0"
		table.insert(playersUsingMic, {source, p_id})
	end
end
addEventHandler("onClientPlayerVoiceStart", root, onStartVoiceChat)

function onStopVoiceChat()
	for i, v in ipairs(playersUsingMic) do
		if (v[1] == source) then
			table.remove(playersUsingMic, i)
		end
	end
end
addEventHandler("onClientPlayerVoiceStop", root, onStopVoiceChat)

function drawText()
	if (#playersUsingMic > 0) then
		for i, v in ipairs(playersUsingMic) do
			dxDrawText("Talk: "..getPlayerName(v[1]).." ["..v[2].."]", x * (27/sx), i*30 + y * (341/sy), x * (294/sx), i*30 + y * (376/sy), tocolor(255, 255, 255, 255), 1.00, "default-bold", "left", "top", false, false, false, false, false)
		end
	end
end
addEventHandler("onClientRender", root, drawText)


function getMyValue(player)
	for i, v in ipairs(playersUsingMic) do
		if v[1] == player then
			return i
		end
	end
end

 

Edited by HassoN
  • Like 1
Link to comment
13 hours ago, HassoN said:

Sorry for late response, I was sleeping. ?


local playersUsingMic = {}
local x, y = guiGetScreenSize ( )
local sx, sy = 1600, 900

function onStartVoiceChat()
	local myIndex = getMyValue(source)
	if (not myIndex or not playersUsingMic[myIndex]) then
		local p_id = getElementData (source, "ID") or "0"
		table.insert(playersUsingMic, {source, p_id})
	end
end
addEventHandler("onClientPlayerVoiceStart", root, onStartVoiceChat)

function onStopVoiceChat()
	for i, v in ipairs(playersUsingMic) do
		if (v[1] == source) then
			table.remove(playersUsingMic, i)
		end
	end
end
addEventHandler("onClientPlayerVoiceStop", root, onStopVoiceChat)

function drawText()
	if (#playersUsingMic > 0) then
		for i, v in ipairs(playersUsingMic) do
			dxDrawText("Talk: "..getPlayerName(v[1]).." ["..v[2].."]", x * (27/sx), i*30 + y * (341/sy), x * (294/sx), i*30 + y * (376/sy), tocolor(255, 255, 255, 255), 1.00, "default-bold", "left", "top", false, false, false, false, false)
		end
	end
end
addEventHandler("onClientRender", root, drawText)


function getMyValue(player)
	for i, v in ipairs(playersUsingMic) do
		if v[1] == player then
			return i
		end
	end
end

 

The main thing that you could help, thanks!

Another question, need to make this inscription appear within 15 meters.

I mean, now any player will click on the microphone button and it will display what he says BUT i need

so that it is displayed within 15 meters of the player.

For example, on the server 3 people. 2 players are together and the third is in a different place.

If a third player will talk, the first and second should not see the inscription because they are far from the player.

and the first and second players will see each other's inscriptions.

I hope I correctly explained what I need.

Can you help me with this?

Link to comment
27 minutes ago, slapz0r said:

The main thing that you could help, thanks!

Another question, need to make this inscription appear within 15 meters.

I mean, now any player will click on the microphone button and it will display what he says BUT i need

so that it is displayed within 15 meters of the player.

For example, on the server 3 people. 2 players are together and the third is in a different place.

If a third player will talk, the first and second should not see the inscription because they are far from the player.

and the first and second players will see each other's inscriptions.

I hope I correctly explained what I need.

Can you help me with this?

Try this

local playersUsingMic = {}
local x, y = guiGetScreenSize ( )
local sx, sy = 1600, 900

function onStartVoiceChat()
	local x, y, z = getElementPosition(source)
	local x2, y2, z2 = getElementPosition(localPlayer)
	local distance = getDistanceBetweenPoints3D(x, y, z, x2, y2, z2)
	if (distance <= 15) then
		local myIndex = getMyValue(source)
		if (not myIndex or not playersUsingMic[myIndex]) then
			local p_id = getElementData (source, "ID") or "0"
			table.insert(playersUsingMic, {source, p_id})
		end
	end
end
addEventHandler("onClientPlayerVoiceStart", root, onStartVoiceChat)

function onStopVoiceChat()
	for i, v in ipairs(playersUsingMic) do
		if (v[1] == source) then
			table.remove(playersUsingMic, i)
		end
	end
end
addEventHandler("onClientPlayerVoiceStop", root, onStopVoiceChat)

function drawText()
	if (#playersUsingMic > 0) then
		for i, v in ipairs(playersUsingMic) do
			dxDrawText("Talk: "..getPlayerName(v[1]).." ["..v[2].."]", x * (27/sx), i*30 + y * (341/sy), x * (294/sx), i*30 + y * (376/sy), tocolor(255, 255, 255, 255), 1.00, "default-bold", "left", "top", false, false, false, false, false)
		end
	end
end
addEventHandler("onClientRender", root, drawText)


function getMyValue(player)
	for i, v in ipairs(playersUsingMic) do
		if v[1] == player then
			return i
		end
	end
end

 

  • Like 1
Link to comment
12 minutes ago, HassoN said:

Try this


local playersUsingMic = {}
local x, y = guiGetScreenSize ( )
local sx, sy = 1600, 900

function onStartVoiceChat()
	local x, y, z = getElementPosition(source)
	local x2, y2, z2 = getElementPosition(localPlayer)
	local distance = getDistanceBetweenPoints3D(x, y, z, x2, y2, z2)
	if (distance <= 15) then
		local myIndex = getMyValue(source)
		if (not myIndex or not playersUsingMic[myIndex]) then
			local p_id = getElementData (source, "ID") or "0"
			table.insert(playersUsingMic, {source, p_id})
		end
	end
end
addEventHandler("onClientPlayerVoiceStart", root, onStartVoiceChat)

function onStopVoiceChat()
	for i, v in ipairs(playersUsingMic) do
		if (v[1] == source) then
			table.remove(playersUsingMic, i)
		end
	end
end
addEventHandler("onClientPlayerVoiceStop", root, onStopVoiceChat)

function drawText()
	if (#playersUsingMic > 0) then
		for i, v in ipairs(playersUsingMic) do
			dxDrawText("Talk: "..getPlayerName(v[1]).." ["..v[2].."]", x * (27/sx), i*30 + y * (341/sy), x * (294/sx), i*30 + y * (376/sy), tocolor(255, 255, 255, 255), 1.00, "default-bold", "left", "top", false, false, false, false, false)
		end
	end
end
addEventHandler("onClientRender", root, drawText)


function getMyValue(player)
	for i, v in ipairs(playersUsingMic) do
		if v[1] == player then
			return i
		end
	end
end

 

OK, everything is great

Another caveat, how to deal with this?

For example, you are 14 meters from the player, he pressed a button - you see his inscription - everything is fine

If he presses the button, and at that time you will have another 5 meters from him, that is, there will already be 19 meters

You will have an inscription (this is on the condition that he has the button still clamped), can it be done so when the player has the button clamped and you go beyond 15 meters the inscription disappears?

Link to comment
5 minutes ago, HassoN said:

Explain more, I don't get it.

For example, you are 14 meters away from the player, he will press the button - you will see the inscription - it's fine

you are 16 meters away from the player, he will press the button - the inscription you will not see - it's fine

The player presses (and holds) the button (at this time you are 16 meters away) - the inscription can't see

The player does not release the button, and at this time you are go to the player (and now the distance is already 14 meters) 

The player did not release the button and you do not see the inscription. Of course, if the player releases the button and presses again - you will see the inscription. But we are talking about the holding button.

 

Link to comment
59 minutes ago, slapz0r said:

For example, you are 14 meters away from the player, he will press the button - you will see the inscription - it's fine

you are 16 meters away from the player, he will press the button - the inscription you will not see - it's fine

The player presses (and holds) the button (at this time you are 16 meters away) - the inscription can't see

The player does not release the button, and at this time you are go to the player (and now the distance is already 14 meters) 

The player did not release the button and you do not see the inscription. Of course, if the player releases the button and presses again - you will see the inscription. But we are talking about the holding button.

 

I've checked the available functions/events but I couldn't find anything useful for your case.

  • Like 1
Link to comment
3 minutes ago, N3xT said:

You can use onClientRender for this, and check his position

Getting player's position with onClientRender is totally inefficient for the server's performance, you could've suggested something a little bit better like setting a timer. But either ways, you can't use either of them because there's no function which checks if X player is using his mic.

Link to comment

You got it wrong. using onClientRender correctly won't harm the server performance at all there's a lot of scripts using the same method, for example, race name tags and there's more and more

also, you can use variables with onClientPlayerVoiceStart & onClientPlayerVoiceStop to determine if the player using his microphone or not, however, you don't need this because you've already inserted the players using their microphones into a table so you can use this too.

Edited by N3xT
Link to comment
2 minutes ago, N3xT said:

You got it wrong. using onClientRender correctly won't harm the server performance at all there are a lot of scripts using the same method, for example, race name tags and there's more and more

also, you can use variables with onClientPlayerVoiceStart & onClientPlayerVoiceStop to determine if the player using his microphone or not, however, you don't need this because you've already inserted the players using their microphones into a table so you can use this too.

Race name tags? do you mean dx functions? Then onClientRender is obviously a must.

I am trying to advise the topic's owner to the least inefficient method. So I still believe using onClientRender to get someone's position is totally unnecessary and could be simply replaced by a timer.

About your suggestion, that could be a good idea but in my tables, players get added to the table only if they are close to the local player so you can't actually use them to check because in this case, players don't get added to the table in the first place because they keep holding the button.

Maybe adding another table which includes all players who are using mics (even if they are far away) then using a timer to check if someone from that table gets close enough to the local player so we add him to the 2nd table (which is used to show close players) should work.

Link to comment
6 hours ago, HassoN said:

Race name tags? do you mean dx functions? Then onClientRender is obviously a must.

I am trying to advise the topic's owner to the least inefficient method. So I still believe using onClientRender to get someone's position is totally unnecessary and could be simply replaced by a timer.

About your suggestion, that could be a good idea but in my tables, players get added to the table only if they are close to the local player so you can't actually use them to check because in this case, players don't get added to the table in the first place because they keep holding the button.

Maybe adding another table which includes all players who are using mics (even if they are far away) then using a timer to check if someone from that table gets close enough to the local player so we add him to the 2nd table (which is used to show close players) should work.

I'm not talking about dx functions, a lot of developers thinks that using anything but dx functions inside a render is wrong and might harm your server and things like that, I'm not saying that's true nor false. depends on the way you use the render but do you think using a function like getElementPosition inside a render is wrong? totally not.

when I told you race nametags are using the same method I meant getting the position of the player and calculating the scale of the text and we've been using it for years now and I've never seen anybody complain about it, you can check race gamemode and you'll get the full picture of what I'm talking about.

and yeah, the same goes for timers.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...