CREDITS:
From "I'm presenting you the future" series:
Bubble Chat !
The easiest way to chat with your friends
You type a message, it appears near your ped
It's invisible for you, but visible for the others around you
It's attached to you
Gets auto-removed after few seconds
It's auto-scaling, depending on your resolution
(https://forum.vc-mp.org/proxy.php?request=http%3A%2F%2Fi.imgur.com%2FgKq7HOB.jpg&hash=137558eecdebdfb043691752ab187c4edabb21c5) (http://i.imgur.com/gKq7HOB.jpg)
[spoiler=how it reacts when text.len() > 25]
(https://forum.vc-mp.org/proxy.php?request=http%3A%2F%2Fi.imgur.com%2Fb6MUIN6.png&hash=8864d8a6a71f9a3910d03fda2628708efc4c9efb) (http://i.imgur.com/b6MUIN6.png)
[/spoiler]
[spoiler=Instalation guide]
SCRIPT-SIDEfor the top:enum StreamType
{
BubbleChat = 0x01
};
onPlayerChat( player, chat )local Stream = Stream();
Stream.WriteByte( StreamType.BubbleChat );
Stream.WriteInt( player.ID );
if( text.len() > 25 )
{
text = "(" + text.slice( 0, 20 ) + "...)";
}
Stream.WriteString( text );
Stream.SendStream( null );
CLIENT-SIDEfor the top:MAX_PLAYERS <- 50; // change it with your Max Players' Limit !
enum StreamType
{
BubbleChat = 0x01
}
local ChatBubble_UI = array( MAX_PLAYERS );
local ChatBubble_Sender = array( MAX_PLAYERS );
local ChatBubble_Frames = array( MAX_PLAYERS, 0 );
// Would've made these constant as well but:
// ChatBubble_Colour is not a primitive
// ChatBubble_Scale may be adjusted in windowed mode
local ChatBubble_Colour = Colour( 255, 255, 255 );
// I'm guessing these can be considered constant
const ChatBubble_Alpha = 255;
const ChatBubble_Font = "Verdana";
local ChatBubble_Flag = GUI_FFLAG_OUTLINE;
Script::ScriptProcess( ) ::ChatBubbleProc();
Server::ServerData( stream ) local type = stream.ReadByte();
switch(type)
{
case StreamType.BubbleChat:
local pID = stream.ReadInt();
::ChatBubbleSetData( pID, World.FindPlayer( pID ), stream.ReadString() );
break;
}
Bubble Chat functions//-------------------------------------------
function ChatBubbleSetData( index, player, text )
{
// We create the label locally first
local lbl = GUILabel( VectorScreen( 0, 0 ), ChatBubble_Colour, "" );
// Configure the label
lbl.FontSize = (GUI.GetScreenSize().Y / 40);
//lbl.FontName = ChatBubble_Font; // commented because it gives 1ms freeze
lbl.Alpha = ChatBubble_Alpha;
//lbl.FontFlags = ChatBubble_Flag; // commented because it gives 1-2ms freeze
lbl.Text = text;
// Only after we know the label was created and configured we save it
ChatBubble_UI[ index ] = lbl;
// At this point we can store the associated player
//ChatBubble_Sender[ index ] = player;
// Only after everything is successful we reset the frame counter
ChatBubble_Frames[ index ] = 0;
}
//-------------------------------------------
function Distance( x1, y1, z1, x2, y2, z2 )
{
return sqrt( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2) );
}
//-------------------------------------------
function ChatBubbleProc()
{
local lplayer = World.FindLocalPlayer(), sender;
local lpos = lplayer.Position, spos;
local lbl, wpts, z1 = Vector( 0, 0, 1 );
// We know there are as many frame counters as senders and we can use their index as limit
for (local i = 0, maxi = ChatBubble_Frames.len(); i < maxi; ++i)
{
if( ChatBubble_UI[ i ] && ChatBubble_Frames[ i ] <= 450 )
{
// Stop this whole shenanigan here if:
// the text was updated more than 450 frames ago
// or:
// the text does not even exists anymore
if( ChatBubble_Frames[i] >= 450 || ChatBubble_UI[i] == null )
{
// We can just ignore this index...
}
// Don't process if the text was updated more than 450 frames ago
else if( ++ChatBubble_Frames[i] == 450 || !World.FindPlayer( i ) )
{
ChatBubble_UI[ i ] = null;
ChatBubble_Sender[ i ] = null;
}
// Don't process if there's no sender
else if( sender = ChatBubble_Sender[ i ] && World.FindPlayer( i ) )
{
spos = sender.Position, lbl = ChatBubble_UI[ i ], lbl.Alpha = 0;
// See if the sender is within local player range
if( Distance( lpos.X, lpos.Y, lpos.Z, spos.X, spos.Y, spos.Z ) < 20 )
{
wpts = GUI.WorldPosToScreen( spos + z1 );
lbl.Position = VectorScreen( wpts.X, wpts.Y );
local ChatBubble_PosToScreen = GUI.WorldPosToScreen( spos );
if( ChatBubble_PosToScreen.Z < 1)
{
lbl.Alpha = ChatBubble_Alpha;
}
else
{
lbl.Alpha = 0;
}
}
if( sender == lplayer )
{
lbl.Alpha = 0;
}
}
}
}
}
//-------------------------------------------
[/spoiler]
Nice Job Seby! ;D
cool for roleplay
cool
Nice work. I really like that bubble chat :D
I got a question to ask:-
In your client side code, the locals:-
local ChatBubble_UI = array( GetMaxPlayers );
local ChatBubble_Sender = array( GetMaxPlayers );
local ChatBubble_Frames = array( GetMaxPlayers, 0 );
Isn't GetMaxPlayers a function? The last time I used it, it was a function, not a variable. I don't know about client side, but in server-side its a function. Please check it :)
That just reminded me of
@EK.IceFlake's server.
Quote from: KAKAN on Mar 08, 2017, 01:50 PMIsn't GetMaxPlayers a function? The last time I used it, it was a function, not a variable. I don't know about client side, but in server-side its a function. Please check it :)
Actually, it is a variable in this case, since there is no client-side function like GetMaxPlayers();
It's just the way I named it. I will change it to MAX_PLAYERS in order to not get confused again.
PS: Done.
Quote from: Xmair on Mar 08, 2017, 04:14 PMThat just reminded me of @EK.IceFlake's server.
Interesting. Never knew that.
This just accentuates the need of such a feature in every server. :)
His server is still in beta and was password locked but he let me in :p
Quote from: Xmair on Mar 08, 2017, 05:26 PMHis server is still in beta and was password locked but he let me in :p
me too :)
Quote from: sseebbyy on Mar 08, 2017, 05:16 PMQuote from: KAKAN on Mar 08, 2017, 01:50 PMIsn't GetMaxPlayers a function? The last time I used it, it was a function, not a variable. I don't know about client side, but in server-side its a function. Please check it :)
Actually, it is a variable in this case, since there is no client-side function like GetMaxPlayers();
It's just the way I named it. I will change it to MAX_PLAYERS in order to not get confused again.
PS: Done.
What's the need of variables? Just set them to 100, they won't eat 1GB of RAM. I usually prefer that :P
Quote from: KAKAN on Mar 08, 2017, 06:41 PMWhat's the need of variables? Just set them to 100, they won't eat 1GB of RAM. I usually prefer that :P
Then you'd be processing 50 or more players that don't exist. And you'll be doing that on each frame. It's not an error but it's a waste of processing power.
Quote from: KAKAN on Mar 08, 2017, 06:41 PMWhat's the need of variables? Just set them to 100, they won't eat 1GB of RAM. I usually prefer that :P
I prefer to set a variable for it, to change it easily when in need.
There is no need for more, if we know the exact amount.
Hotfix
ChatBubbleProc() was updated to avoid server crash.
PS: I also put an e.g. of MAX_PLAYERS variable, so everybody can be aware of it.
Also, don't forget to set it's value to be the same as the maximum amount of players that can be on your server.
A question of curiosity, when a player is afk and I speak next to him and the player immediately returns. The question is, does he see the message I wrote? Another, if the player is in motion, the text follows to player?...
Quote from: kennedyarz on Mar 11, 2017, 01:32 PMA question of curiosity, when a player is afk and I speak next to him and the player immediately returns. The question is, does he see the message I wrote? Another, if the player is in motion, the text follows to player?...
The message is shown near his head once it is sent to the chat.
And yes, it follows the player. (I said it is "attached")
Quote from: sseebbyy on Mar 11, 2017, 01:40 PMQuote from: kennedyarz on Mar 11, 2017, 01:32 PMA question of curiosity, when a player is afk and I speak next to him and the player immediately returns. The question is, does he see the message I wrote? Another, if the player is in motion, the text follows to player?...
The message is shown near his head once it is sent to the chat.
And yes, it follows the player. (I said it is "attached")
The truth is that I have already tried 2 times this script and I do not see it, I am putting everything perfectly as you know, the problem is that I open 2 windows of the vcmp and connect it to my test server, I then send a message and like the other one Window is afk. Then I immediately return to the other window and I do not see the message in his head. The problem will be because a window is afk?
Quote from: kennedyarz on Mar 11, 2017, 01:45 PMThen I immediately return to the other window and I do not see the message in his head. The problem will be because a window is afk?
I tested the script only în windowed mode, but I will do a test later with it turned off.
Btw, Is the client-side script even loaded?
You can check that by sending a message to the console when script loads.
Quote from: sseebbyy on Mar 11, 2017, 02:14 PMQuote from: kennedyarz on Mar 11, 2017, 01:45 PMThen I immediately return to the other window and I do not see the message in his head. The problem will be because a window is afk?
I tested the script only în windowed mode, but I will do a test later with it turned off.
Btw, Is the client-side script even loaded?
You can check that by sending a message to the console when script loads.
The truth is that I am currently testing on a blank server and it works perfect. But on the other I'm not doing anything wrong and it's not working. Anyway, I'm going to look deeper to see that it's wrong.
Working now
Yeah, I had something similar in Liberty Unleashed. Any GUI element can be used (windows, images, etc)
http://forum.liberty-unleashed.co.uk/index.php/topic,1770.0.html
You can put clan logos above people's heads with it.
nICE Perfect Seby "Lucker
can you make it like a something here like UpThen The Bank door you can see {Bank Door}
and it never del ?
@Sebastian Thx :D
Quote from: Mahmoud Tornado on Aug 26, 2017, 05:43 PMcan you make it like a something here like UpThen The Bank door you can see {Bank Door}
and it never del ? @Sebastian Thx :D
Check your pm.
NICE JOB Seby gen
Why can't I work?
error invalid constant [StreamType.BubbleChat]
Some friend implemented this in a blank server and complained about lag.
Kept looking around to see why it doesn't lag for me though, and realized this:
Setting the font name of a label gives a small freeze moment too, while setting the flag GUI_FFLAG_OUTLINE has a huge impact which makes the game completely freeze for 1-2ms.
So, in order to get rid of this, comment the 2 lines like I did here:
in function ChatBubbleSetData( index, player, text )
// lbl.FontName = ChatBubble_Font;
// lbl.FontFlags = ChatBubble_Flag;
Also, for a better gameplay, I recommend setting the font size like this: ( val 40 instead of 27 )
lbl.FontSize = ( sY / 40 );
PS: Though, there are some settings we can do to have the full text of a player, wrapped around, to appear next to the player.
This way, we don't need to cut the text anymore. Unfortunately, I'm not yet aware of how things work; maybe will take a look at some point.