[Release] Bubble Chat

Sebastian

  • VC:MP Beta Tester
  • Something like this: hga hga hga
  • Posts: 946
[Release] Bubble Chat
« on March 8th, 2017, 12:35 PM »Last edited on March 8th, 2017, 11:29 PM
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



(click to show/hide)




(click to show/hide)
SCRIPT-SIDE

for the top:
Code: [Select]
enum StreamType
{
BubbleChat = 0x01
};

onPlayerChat( player, chat )
Code: [Select]
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-SIDE

for the top:
Code: [Select]
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( )
Code: [Select]
::ChatBubbleProc();

Server::ServerData( stream )
Code: [Select]
local type = stream.ReadByte();

switch(type)
{
case StreamType.BubbleChat:
            local pID = stream.ReadInt();
            ::ChatBubbleSetData( pID, World.FindPlayer( pID ), stream.ReadString() );
        break;
}

Bubble Chat functions
Code: [Select]
//-------------------------------------------
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 / 27);
    lbl.FontName = ChatBubble_Font;
    lbl.Alpha = ChatBubble_Alpha;
    lbl.FontFlags = ChatBubble_Flag;
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;
}
}
}
    }
}

//-------------------------------------------


MatheuS

  • Wiki Contributor
  • LBR | Co-Leader & Brasil Real RPG | Developer
  • Posts: 449
[Release] Re: Bubble Chat
« Reply #1, on March 8th, 2017, 01:10 PM »
Nice Job Seby! ;D
Code: [Select]
if( !sucess ) tryAgain();

vito

  • Sr. Member
  • Posts: 406
[Release] Re: Bubble Chat
« Reply #2, on March 8th, 2017, 01:16 PM »
cool for roleplay

kennedyarz

  • Sr. Member
  • Making American Great Again
  • Posts: 334

KAKAN

  • Wiki Contributor
  • Posts: 3,346
[Release] Re: Bubble Chat
« Reply #4, on March 8th, 2017, 01:50 PM »Last edited on March 8th, 2017, 01:53 PM
Nice work. I really like that bubble chat :D

I got a question to ask:-
In your client side code, the locals:-
Code: [Select]
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 :)
You can contact me using Discord, at Developers.CPP( check off-board to find the invite link )
Github: https://github.com/theKAKAN

Xmair

  • Wiki Contributor
  • Posts: 879
VU Full Member | VCCNR Developer | KTB Developer | EAD Ex-Scripter

Sebastian

  • VC:MP Beta Tester
  • Something like this: hga hga hga
  • Posts: 946
[Release] Re: Bubble Chat
« Reply #6, on March 8th, 2017, 05:16 PM »
Quote from KAKAN on March 8th, 2017, 01:50 PM
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 :)
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 March 8th, 2017, 04:14 PM
That just reminded me of @EK.IceFlake's server.
Interesting. Never knew that.
This just accentuates the need of such a feature in every server. :)

Xmair

  • Wiki Contributor
  • Posts: 879
[Release] Re: Bubble Chat
« Reply #7, on March 8th, 2017, 05:26 PM »
His server is still in beta and was password locked but he let me in :p
VU Full Member | VCCNR Developer | KTB Developer | EAD Ex-Scripter

KAKAN

  • Wiki Contributor
  • Posts: 3,346
[Release] Re: Bubble Chat
« Reply #8, on March 8th, 2017, 06:41 PM »
Quote from Xmair on March 8th, 2017, 05:26 PM
His server is still in beta and was password locked but he let me in :p
me too :)
Quote from sseebbyy on March 8th, 2017, 05:16 PM
Quote from KAKAN on March 8th, 2017, 01:50 PM
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 :)
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
You can contact me using Discord, at Developers.CPP( check off-board to find the invite link )
Github: https://github.com/theKAKAN

.

  • VC:MP Beta Tester
  • .
  • Posts: 1,804
[Release] Re: Bubble Chat
« Reply #9, on March 8th, 2017, 07:03 PM »
Quote from KAKAN on March 8th, 2017, 06:41 PM
What'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.
.

Sebastian

  • VC:MP Beta Tester
  • Something like this: hga hga hga
  • Posts: 946
[Release] Re: Bubble Chat
« Reply #10, on March 8th, 2017, 07:08 PM »
Quote from KAKAN on March 8th, 2017, 06:41 PM
What'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.
[Release] Re: Bubble Chat
« Reply #11, on March 8th, 2017, 11:27 PM »Last edited on March 8th, 2017, 11:30 PM
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.

kennedyarz

  • Sr. Member
  • Making American Great Again
  • Posts: 334
[Release] Re: Bubble Chat
« Reply #12, on March 11th, 2017, 01:32 PM »
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?...

Sebastian

  • VC:MP Beta Tester
  • Something like this: hga hga hga
  • Posts: 946
[Release] Re: Bubble Chat
« Reply #13, on March 11th, 2017, 01:40 PM »
Quote from kennedyarz on March 11th, 2017, 01:32 PM
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?...
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")

kennedyarz

  • Sr. Member
  • Making American Great Again
  • Posts: 334
[Release] Re: Bubble Chat
« Reply #14, on March 11th, 2017, 01:45 PM »
Quote from sseebbyy on March 11th, 2017, 01:40 PM
Quote from kennedyarz on March 11th, 2017, 01:32 PM
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?...
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?