Ok. So everyone here knows I am a big fan of Kleshik.
But it's not just because it's bad ass! OK MOSTLY it's because it's BADASS! But the other reason is because the code is so well done! Anyway, there is this simple but over looked feature in Kleshik that displays a sprite bubble over the heads of the person who is chatting at the time. So simple yet I often wonder why this little feature isn't in more multiplayer mods. It is so damn simple to implement it is crazy. 
Now it is time to hopefully remedy that problem. With this tut there is no excuse not to throw it in there.
If you get real creative you can make your own custom sprite for this! Also, you could use this same method to display all kinds of interesting information over a players head during game play depending on specific conditions to be met. The method would be similar. I'm hoping this sparks some creative uses for such a method. This isn't anything new in terms of code. This is used all the time in QC. But this is so simple and such a useful feature it should be in any multiplayer mod!
One Note: This code assumes using dpextensions.qc but you can easily modify this code to use existing QC effects that will work with any engine. This applies to setattachment, EF_FULLBRIGHT and EF_NODRAW which is used in this tutorial.
This tut will work out of the box with FTE or DP.
So basically to start with open up progs.src and go down to client.qc. Right before that go ahead and place chatbubble.qc and save.
Ok, now we need to create chatbubble.qc. In it you will be placing this code:
Ok hopefully the green highlights will help to explain what is going on. We will need to have something that can remove the sprite in case a client leaves the server but still had the indicator visible.
Next we create the routine that will update the status of the indicator to yourself and everyone else and if it hasn't been already, spawn the entity above the clients head. In order for this to work tho, we will need to use the routine below it to actually check for whether the messagemode is active and change the conditions to true or false accordingly so that the update routine will know what to do.
Ok, that was the only hard thing to do. Save that file and lets open up client.qc.
Scrolls down to PlayerPostThink () and before deadflag check place this:
We call this routine here because PlayerPostThink is always running and so this will ensure this check is always being done while the client is connected. Ok that is if for that routine. Now move down to ClientDisconnect () and right after gameover check put this:
Ok. That is it. Save that file. Compile and you are ready. This of course will only really work in multiplayer. COOP or Deathmatch. In singleplayer the game actually freezes when you go into messagemode so to test it out start up a multiplayer game and if you are alone just use chase_active 1 to see it. If I left anything out let me know. I hope you can use this in creative ways. Thanks a ton to Dresk for his code that I modified here. If anyone needs help setting this up without the need for dpextensions let me know but the process "should" be self explanatory. Enjoy!


Now it is time to hopefully remedy that problem. With this tut there is no excuse not to throw it in there.


One Note: This code assumes using dpextensions.qc but you can easily modify this code to use existing QC effects that will work with any engine. This applies to setattachment, EF_FULLBRIGHT and EF_NODRAW which is used in this tutorial.
This tut will work out of the box with FTE or DP.
So basically to start with open up progs.src and go down to client.qc. Right before that go ahead and place chatbubble.qc and save.
Code:
weapons.qc world.qc [COLOR="Lime"]chatbubble.qc[/COLOR] client.qc player.qc monsters.qc
Code:
[COLOR="Lime"]// These need to be declared first which will be used below in several routines[/COLOR] .entity chatbubble; .float chatvisible; [COLOR="Lime"]// This float will be used to remove the indicator if the client disconnects from the server - used in client.qc[/COLOR] float removebubble(entity bowner, .entity bubbles) { if(bowner.bubbles) { remove(bowner.bubbles); bowner.bubbles = world; return TRUE; } else return FALSE; } [COLOR="lime"]// This routine will update the status of the chat indicator depending on if it should be displayed or not.[/COLOR] void updateclientchat(entity bclient, float bvisible) { if(bvisible) { if(bclient.chatbubble) bclient.chatbubble.effects = bclient.chatbubble.effects - (bclient.chatbubble.effects & EF_NODRAW); else { [COLOR="lime"]//This is the information we need to spawn the bubble and make it visible to all other clients [/COLOR] local entity bubble; bubble = spawn(); [COLOR="lime"]//It's there! :)[/COLOR] setmodel(bubble, "progs/s_bubble.spr"); bubble.effects = EF_FULLBRIGHT; [COLOR="Lime"]//Here you could use EF_DIMLIGHT instead for non DP/FTE engines. [/COLOR] bubble.scale = 1.2; [COLOR="lime"]//Size of the sprite[/COLOR] bubble.alpha = 0.6; [COLOR="lime"]// How see through the sprite will be[/COLOR] bubble.colormod = '1 0 0'; [COLOR="lime"]//This is whatever color you want to highlight the sprite in. (RGB) from left to right. [/COLOR] setorigin(bubble, bubble.origin + '0 0 0.5' + bclient.maxs_z * '0 0 1'); [COLOR="Lime"]//Instructions on where to place the indicator over the head of the player using xyz coords and a limit on the max height possible to adjust for changes while player moves up or down. [/COLOR] bclient.chatbubble = bubble; setattachment(bubble, bclient, ""); [COLOR="lime"]//This allows other clients to see the entity. In order to accomplish this without using this dp extension you can assign this entity MOVETYPE_FOLLOW. But when possible, setattachment syncs much better :)[/COLOR] } bclient.chatvisible = TRUE; } else { if(bclient.chatbubble) bclient.chatbubble.effects = bclient.chatbubble.effects | EF_NODRAW; [COLOR="lime"]//If you want to use a non dp extension to turn off the indicator just simply use remove(self) and that will basically do the same thing but will need to change the base code slightly to compensate for change. [/COLOR] bclient.chatvisible = FALSE; } } [COLOR="lime"]//This is used in client.qc (PlayerPostThink) to check if client has pressed the message button and if so set the conditions accordingly and run the update check.[/COLOR] void checkclientchat(entity bclient) { if(bclient.buttonchat) { if(!bclient.chatvisible) updateclientchat(bclient, TRUE); } else { if(bclient.chatvisible) updateclientchat(bclient, FALSE); } }
Next we create the routine that will update the status of the indicator to yourself and everyone else and if it hasn't been already, spawn the entity above the clients head. In order for this to work tho, we will need to use the routine below it to actually check for whether the messagemode is active and change the conditions to true or false accordingly so that the update routine will know what to do.
Ok, that was the only hard thing to do. Save that file and lets open up client.qc.
Scrolls down to PlayerPostThink () and before deadflag check place this:
Code:
[COLOR="lime"]checkclientchat(self); [/COLOR] if (self.deadflag) return;
Code:
if (gameover) return; [COLOR="lime"]removebubble (self, chatbubble);[/COLOR]

Comment