Jump to content

Chat System


Recommended Posts

2 hours ago, #DeltaSCR said:

Ai pra exibir a tela de mensagens pros dois players, no onClientRender, eu teria que colocar o argumento do player obtido na Grid?


function createCEGUI()
	theWindow = guiCreateWindow(0.27, 0.23, 0.45, 0.53, "Companhia Telefonica TSB", true)
	guiWindowSetMovable(theWindow, false)
	guiWindowSetSizable(theWindow, false)
	--// EDITS
	memoChat = guiCreateMemo(0.02, 0.08, 0.96, 0.78, "\n", true, theWindow)
	editText = guiCreateEdit(0.02, 0.89, 0.97, 0.08, "Digite sua mensagem aqui...", true, theWindow)
end

function DeltaSCR_Click(button, state, absoluteX, absoluteY)
	if button ~= "left" then
		return
	end
	if state == "down" then
		local namePlayer = guiGridListGetItemText(playersList, row, column)
		local thePlayer = getPlayerFromName(namePlayer)
	end
end
addEventHandler("onClientGUIClick", playerList, DeltaSCR_Click, false)

 

Você não usou guiGridListGetSelectedItem para identificar qual linha/coluna foi selecionada.

Dica: Tente fazer tudo com gui que é mais fácil, e se der certo, você muda e coloca algumas frescuras de dx.

  • Haha 1
Link to comment
  • Other Languages Moderators

@#DeltaSCR Arrume a indentação, pra começar. Depois faça assim:

addEventHandler("onClientResourceStart", resourceRoot, function ()
	playersList = guiCreateGridList (0.30, 0.28, 0.11, 0.49, true) -- Gridlist com tamanho e posição relativa não é recomendável.
	local column = guiGridListAddColumn (playersList, "Jogadores", 0.9)
	if (column) then
		for _, player in ipairs (getElementsByType("player")) do
			guiGridListAddRow (playersList, string.gsub (getPlayerName(player), "#%x%x%x%x%x%x", "")) -- Adiciona os nomes dos jogadores sem código #hex. O getPlayerName não funcionará mais neste caso, pois o nome precisa ser exato com os códigos de cor. Usa-se getPlayerPartialName em vez disso.
		end
	end
	guiSetAlpha (playersList, 0.8)
	guiSetVisible (playersList, false)
end)

function createCEGUI ()
	theWindow = guiCreateWindow (0.27, 0.23, 0.45, 0.53, "Companhia Telefonica TSB", true)
	guiWindowSetMovable (theWindow, false)
	guiWindowSetSizable (theWindow, false)
	--// EDITS
	memoChat = guiCreateMemo (0.02, 0.08, 0.96, 0.78, "\n", true, theWindow)
	editText = guiCreateEdit (0.02, 0.89, 0.97, 0.08, "Digite sua mensagem aqui...", true, theWindow)
end

function DeltaSCR_Click (button, state, absoluteX, absoluteY)
	if button ~= "left" or state ~= "down" then return end -- Se o botão usado para o clique não for o esquerdo ou o botão não estiver sendo apertado, então nada acontece.
	local row = guiGridListGetSelectedItem (playersList) -- row recebe o índice da linha selecionada, sendo 0 se for a primeira linha, 1 se for a segunda e assim por diante.
	if row >= 0 then -- Se existe algum item selecionado, então: (row = -1 se nenhum item estiver selecionado)
		local namePlayer = guiGridListGetItemText (playersList, row, 1) -- Recebe o texto do item que estiver na primeira coluna do item selecionado.
		local thePlayer = getPlayerFromPartialName (namePlayer) -- É necessário função útil para isso funcionar, pois namePlayer não tem os códigos de cores.
		-- SEU CÓDIGO AQUI.
	end
end
addEventHandler ("onClientGUIClick", playersList, DeltaSCR_Click, false) -- Estava errado playerList, sem o S

function getPlayerFromPartialName (name) -- Função útil.
	local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil
	if name then
		for _, player in ipairs (getElementsByType("player")) do
			local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower()
			if name_:find(name, 1, true) then
				return player
			end
		end
	end
end

 

5 minutes ago, MaligNos said:

se der certo, você muda e coloca algumas frescuras de dx.

Hahauahauahuahuhauahua

Edited by Lord Henry
Errei a indentação de 1 linha, xD
  • Haha 1
Link to comment

Uma coisa que eu perguntei anteriormente e ainda me ficou a dúvida, como eu vou fazer pra Window aparecer somente para os dois players da conversa? Seria por tabela ou algo do tipo? Se sim, podem me exemplificar?

Edited by #DeltaSCR
Link to comment
Just now, Lord Henry said:

Mas é pra isso mesmo que ela serve. Mostrar a janela (true) ou ocultar a janela (false).

Sim, mas o que eu quero saber é: Onde e como eu posso declarar o player para quem eu quero exibir? Porque assim, se eu deixar somente true, vai exibir para todos os players do servidor.

Realmente, queria muito ajuda, pois nunca trabalhei nessa parte de visibilidade de painéis para outros players...

Link to comment
  • Other Languages Moderators

Isso é client-side, amigo. Só vai acontecer em todos os clientes se no seu triggerClientEvent vc não especificar qual client quer ativar o evento.

Quando alguém clica em um botão num painel, a função que aquele botão ativar no client só vai pra ele. A não ser que vc use um triggerServerEvent pra enviar pra geral via server-side.

Geralmente vc não precisa declarar o jogador em uma função client-side, pois ela só vai pro localPlayer.

Link to comment

Sim, ela vai pro localPlayer, até ai blz, só que eu quero que abra pra outro player tbm, no caso o selecionado na Grid; Esse outro player que está recebendo a "conversa", não precisará fazer nada para abrir, simplesmente aparecerá o GUI

Link to comment
  • Other Languages Moderators

Então, dai vc precisa de um triggerServerEvent e lá no server, fazer um triggerClientEvent no cliente desse outro cara.

É necessário passar o nome do jogador selecionado por parâmetro, dai o server faz o esquema de verificar se o jogador existe com aquele nome, se existir manda o triggerClientEvent pra ele, abrindo o painel nele.

Link to comment
  • Moderators

Um exemplo:

client

addEventHandler("onClientResourceStart", resourceRoot,
	function()
		playersList = guiCreateGridList(0.30, 0.28, 0.11, 0.49, true)
		local column = guiGridListAddColumn(playersList, "Jogadores", 0.9)
		if (column) then
			for _, player in ipairs(getElementsByType("player")) do
			local row = guiGridListAddRow(playersList)
			guiGridListSetItemText (playersList, row, 1, string.gsub(getPlayerName(player), "#%x%x%x%x%x%x", ""), false, false)
			end
		end
		guiSetAlpha(playersList, 0.80)
		guiSetVisible(playersList, false)
	end
)

addEventHandler( "onClientGUIClick", guiRoot, function( b )
    if b ~= "left" then return end
    if source == playersList then
        local playername = guiGridListGetSelectedText(source)
        if playername  and getPlayerFromName(playername) then
            triggerServerEvent( "onClientSelectPlayer", getPlayerFromName(playername) )
        end
    end
end )

function guiGridListGetSelectedText(gridList, columnIndex)
    local selectedItem = guiGridListGetSelectedItem(gridList)
    if (selectedItem) then
        local text = guiGridListGetItemText(gridList, selectedItem, columnIndex or 1)
        if (text) and not (text == "") then
            return text
        end
    end
    return false
end

server

addEvent( "onClientSelectPlayer", true )
addEventHandler( "onClientSelectPlayer", root, function()

    outputChatBox( "O jogador '"..getPlayerName(client).."' iniciou uma conversa com você", source )
    triggerClientEvent( source, "eventname", source ) -- chamar o evento client para o player selecionado
end )

@#DeltaSCR

Edited by DNL291
Link to comment
12 hours ago, DNL291 said:

Um exemplo:

client


addEventHandler("onClientResourceStart", resourceRoot,
	function()
		playersList = guiCreateGridList(0.30, 0.28, 0.11, 0.49, true)
		local column = guiGridListAddColumn(playersList, "Jogadores", 0.9)
		if (column) then
			for _, player in ipairs(getElementsByType("player")) do
			local row = guiGridListAddRow(playersList)
			guiGridListSetItemText (playersList, row, 1, string.gsub(getPlayerName(player), "#%x%x%x%x%x%x", ""), false, false)
			end
		end
		guiSetAlpha(playersList, 0.80)
		guiSetVisible(playersList, false)
	end
)

addEventHandler( "onClientGUIClick", guiRoot, function( b )
    if b ~= "left" then return end
    if source == playersList then
        local playername = guiGridListGetSelectedText(source)
        if playername  and getPlayerFromName(playername) then
            triggerServerEvent( "onClientSelectPlayer", getPlayerFromName(playername) )
        end
    end
end )

function guiGridListGetSelectedText(gridList, columnIndex)
    local selectedItem = guiGridListGetSelectedItem(gridList)
    if (selectedItem) then
        local text = guiGridListGetItemText(gridList, selectedItem, columnIndex or 1)
        if (text) and not (text == "") then
            return text
        end
    end
    return false
end

server


addEvent( "onClientSelectPlayer", true )
addEventHandler( "onClientSelectPlayer", root, function()

    outputChatBox( "O jogador '"..getPlayerName(client).."' iniciou uma conversa com você", source )
    triggerClientEvent( source, "eventname", source ) -- chamar o evento client para o player selecionado
end )

@#DeltaSCR

No caso o evento do client, eu adicionaria na parte de criar a Window, correto?

Link to comment
  • Other Languages Moderators

O código ficaria mais organizado se a janelinha da conversa fosse criada no client, sem usar trigger. O trigger só seria usado para enviar e receber mensagens.

Link to comment
23 minutes ago, asrzk said:

O código ficaria mais organizado se a janelinha da conversa fosse criada no client, sem usar trigger. O trigger só seria usado para enviar e receber mensagens.

E como eu crio ela somente no client? Pq pelo o que eu entendi, se eu deixar ela no somente no cliente, ela vai para o localPlayer somente...

Link to comment

o evento no client, eu vou adicionar na função onde está sendo criada a Window correto?

Tentei fazer mais ou menos assim:

function createCEGUI() --// Aqui a função onde eu crio a Window
	theWindow = guiCreateWindow(0.27, 0.23, 0.45, 0.53, "Companhia Telefonica", true)
	guiWindowSetMovable(theWindow, false)
	guiWindowSetSizable(theWindow, false)
	guiSetVisible(theWindow, false)
	--// EDITS
	memoChat = guiCreateMemo(0.02, 0.08, 0.96, 0.78, "\n", true, theWindow)
	editText = guiCreateEdit(0.02, 0.89, 0.97, 0.08, "Digite sua mensagem aqui...", true, theWindow)
end

function DeltaSCR_Click (button, state, absoluteX, absoluteY, worldX, worldY, worldZ, clickedWorld)
	if button ~= "left" or state ~= "down" then return end
	if isCursorOnElement(screenW * 0.5000, screenH * 0.5000, screenW * 0.1172, screenH * 0.0417) then
		local row = guiGridListGetSelectedItem(playersList)
		if row >= 0 then
			local namePlayer = guiGridListGetItemText(playersList, row, 1)
			local thePlayer = getPlayerFromPartialName(namePlayer)
			guiSetVisible(theWindow, true)
		end
	end
end
addEventHandler("onClientGUIClick", playersList, DeltaSCR_Click, false) --// Estou usando dois eventos pq eu to usando DX e CEGUI...
addEventHandler("onClientClick", getRootElement(), DeltaSCR_Click)

Tipo, o que eu não entendi mesmo até agora foi essa parte da visibilidade

Andei dando uma olhada em alguns resources da comunidade, e pelo o que entendi, vou ter que criar em tabela

Link to comment
  • Other Languages Moderators

Tabelas pra colocar o quê nelas? Jogadores?

Daria pra construir a tabela no server e dar triggerClientEvent só pros jogadores desta tabela:

triggerClientEvent (playersTable, "openChatWindow", resourceRoot)

 

Edited by Lord Henry
Link to comment
  • Other Languages Moderators

Cara, as janelas são criadas client-side. Você deve usar guiSetVisible (janela, false) logo depois de criar a janela, assim ela não vai aparecer pra ninguém. Depois vc mostra ela novamente somente pros jogadores específicos usando triggers. Mas pra isso vc vai precisar mandar pro server, pra ele então mandar pros outros clientes.

client-side:

local x,y = guiGetScreenSize() -- Padrão de qualquer painel.
guiPanel = {} -- Faz todos os elementos GUI dentro de 1 table pra economizar espaço na memória.

function createPanel ()
	-- ======(PAINEL FEITO DE QUALQUER JEITO SÓ DE EXEMPLO)======
	guiPanel["window"] = guiCreateWindow (x/2 - 150, y/2 - 150, 300, 300, "Default Window", false) -- Janela qualquer.
	guiPanel["edit"] = guiCreateEdit (10, 20, 280, 30, "(Nick exato do outro player)", false, guiPanel["window"]) -- Campo de input pra botar o nick do outro jogador. (tem que incluir os códigos de cores, se tiver. No seu caso é uma gridList que funciona diferente disso)
	guiPanel["button1"] = guiCreateButton (300/2 - 50, 300 - 40, 100, 30, "CHAT", false, guiPanel["window"]) -- Botão qualquer, que serve pra ativar o trigger.
	guiSetVisible (guiPanel["window"], false) -- Oculta de cara a janela, pra ela não aparecer pra ninguém.
	-- O painel vai estar criado em todos os clientes, mas não estará visível em nenhum deles.
end
addEventHandler ("onClientResourceStart", resourceRoot, createPanel)

addCommandHandler ("testar", function (cmd) -- Comando qualquer pra fazer o painel aparecer só no cliente que executar o comando.
	guiSetVisible (guiPanel["window"], true)
	showCursor (true) -- Mostra o cursor para poder interagir com o painel.
end)

function interactionPanel (button, state)
	if (button == "left" and state == "up") then -- Verificação de segurança padrão.
		if (source == guiPanel["button1"]) then -- Verificação de botão clicado padrão.
			local theOther = getPlayerFromName(guiGetText(guiPanel["edit"])) -- Recebe o jogador usando o nick informado no campo de input.
			if theOther then -- Se existe um jogador com o nick informado, então:
				guiSetVisible (guiPanel["window"], false) -- Oculta a janela principal.
				guiPanel[guiGetText(guiPanel["edit"])] = guiCreateWindow (x - 400, y/2 - 200, 400, 400, guiGetText(guiPanel["edit"]), false) -- Cria a janela com o nick do outro cara como título.
				triggerServerEvent ("ClientServerChat", theOther) -- Ativa este evento no servidor, usando o outro jogador como source. Isso vai criar a janela no outro cara também, com o nosso nick.
			else
				outputChatBox ("Player não encontrado, informe o nick exato junto com os códigos de cores.")
			end
		end
	end
end
addEventHandler ("onClientGUIClick", guiRoot, interactionPanel) -- (Aprendi esses dias aqui no fórum) guiRoot ativa para todos os elementos GUI deste resource. É mais leve do que root.

function getUpdate (otherPlayer) -- Isso aqui executa no outro jogador. Nós somos o otherPlayer.
	guiPanel[getPlayerName(otherPlayer)] = guiCreateWindow (x - 400, y/2 - 200, 400, 400, getPlayerName(otherPlayer), false) -- Cria a janela com o nick do otherPlayer.
end
addEvent ("ServerClientChat", true) -- Recebe o painel do servidor. Normalmente junto com a mensagem e o jogador que está mandando a mensagem.
addEventHandler ("ServerClientChat", resourceRoot, getUpdate)

server-side:

function transferData () -- Imagine isso apenas como uma ponte entre os clientes. Pode ser usado para tranferência das mensagens.
	triggerClientEvent (source, "ServerClientChat", client) -- source = o outro player | client = o localPlayer de onde veio este evento (nós)
	-- Ativa o evento "ServerClientChat" no cliente do source (outro cara) usando client (nós) como parâmetro de função.
end
addEvent ("ClientServerChat", true) -- Este evento é ativado no servidor pelo nosso cliente.
addEventHandler ("ClientServerChat", resourceRoot, transferData)

 

Edited by Lord Henry
  • Thanks 1
Link to comment

Aproveitando o gancho do tópico, estou com um pequeno erro em um outro código:

Podem me ajudar?

Spoiler

fuujteU.png

 

function giveInsign(thePlayer, cmd, playerName, playerData)
	if (playerData == "natal") then
		local namePlayer = getPlayerFromPartialName(playerName)
		if not (getElementData(namePlayer, "Delta:Natal")) then
			setElementData(namePlayer, "Delta:Natal")
			outputChatBox("INFO: #ffffffVocê deu a insignia de Natal para o Jogador "..namePlayer.."", thePlayer, 200, 50, 0, true)
		else
			outputChatBox("ERRO: #ffffffO Jogador "..namePlayer.." #ffffff já tem essa insignia", thePlayer, 200, 50, 0, true)
		end
	elseif (playerData == "pascoa") then --// AQUI REPETE A MESMA COISA, PORÉM COM OUTRA STRING
end
addCommandHandler("ins", giveInsign)
 
function getPlayerFromPartialName(name)
    local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil
    if name then
        for _, player in ipairs(getElementsByType("player")) do
            local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower()
            if name_:find(name, 1, true) then
                return player
            end
        end
    end
end

 

Link to comment
  • Other Languages Moderators

Opa!

getPlayerName( namePlayer );

Coloque isto acima ^ no lugar de namePlayer, apenas naquelas mensagens de output, pois namePlayer é um elemento.

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...