FragOut! is a Half Life 2 multiplayer mod, in which you only get different kinds of grenades to fight with, instead of the usual weapons. Forcing players to adapt at using only throwing weapons new tactics are sure to arise!
This is a tutorial I wrote up over at the Jailbreak forums on how to mark a player and then show a icon on top of a selected player to track him that's visible even through walls.
Posted by DuckSauce on Jul 2nd, 2009 Page 1 of 3
Intermediate Server Side Coding.
Info and credits:
This tutorial was created with help from Dogmeat(Base Location indicator code) and a little help from the people over at the Steam forums Source Coding section.
The goal in my mod was to have a grenade which when it explodes could "mark" people and that the player who marked them can cycle through his targets at will(you could adapt this to track every target that's marked without too much effort), the player will have to be able to actualy cycle through his targets as in my mod he can push a button to teleport swap with the target(they'll both be teleported to each other's locations).
But since he can hit more then one player in the explosion of the grenade he will need to cycle through targets to get the desired player and as a bonus an icon will be displayed over their head even through walls making it even more usefull for timing the teleport or simply ambushing that player.
Example: You could wait behind a wall, on the other side is a base filled with enemies, you wait for the target to run towards a health pickup in the back of the base, then when you see the icon is far away push the teleport button and voila you will be right behind the enemies forces and can rip them a new one!
Part 1: The HUD Element(client side):
We'll start in the hud element that's gonna show our tracking icon.
In my case it's in a file I called: hud_teleport_marker.cpp in the client side project in the HL2 DLL filter/folder, but you can name it anything you want.
Let's start with the includes which have to be in the top of the file:
My actual class will be called CHudTeleportMarker, but again that can be anything you want it to be.
Now let's look at the header, which can be simply in the .cpp file as long as we won't need to include it anywhere.
First off, important is: m_nTeleportMarkerTextureID which is for the texture of the icon we'll show on the hud. If you don't have a icon you can use for testing I'm willing to send my icon so you can make sure it works.
Even more important is the handle:
A handle is pretty much like a pointer but with some special properties, you can treat it like you would any pointer to a object of a class.
This handle will point to the currently selected player out of our marked players and will be used to fetch this players origin which is used to show the icon on the HUD.
Now the header looks like this:
Next we'll need to use some macro's to set up some stuff:
The second is very important here as this will declare the message that will be hooked to this hud(we'll have to register this message later as well).
Next we'll create the constructor for this class:
The next function will update the marked teleport target(the player who we are tracking), it's a function that will receive a networked usermessage, the usermessage sends a byte(1/4th the size of a normal integer) that contains the entity index of the currently selected player.
Be sure to read data sent in the same order you send it! In this case there's only one byte of data being sent, so there's no order to keep in mind, but if you're gonna send larger message you must read in the same order as you send data or else you'll put the wrong values into your variables.
Next up follow two small functions:
And now the function that's actually gonna paint/draw the tracker image on the screen:
Note that the target pointer gets created in the message receiving function like this(don't insert this code as it's already there):
m_hSelectedMarkedPlayer = UTIL_PlayerByIndex( sender_index );
It will create a C_BasePlayer pointer by fetching the player object by the index we are going to send with WRITE_BYTE which will be stored in an array part of the server side player class.
What's so handy about this system is that you only need to send a players index when the selection changed and that's only sent as a single byte(8 bits), which is then used to create a pointer which can then fetch the origin without sending the Origin vector over the network constantly to keep it updated but rather doing it locally, lowering network traffic.
There may be still be some form of networking going on behind the scenes(how else does the object being pointed to stay updated so that player origin stays correct) but that means we aren't sending it twice over the network so my point stands... lower amount of network traffic.
Next up the last function of the hud element:
This is the code DogMeat used for the base locations, to prevent showing the image when distance is too great or the image is behind the player.
We'll also need to register the usermessage, this is fairly simply, just open up hl2_usermessages.cpp and add:
usermessages->Register( "updateSelectedTeleportTarget", 1 );
Note that according to the Valve Developer Community this is the size in bytes not bits we'll only be sending a byte holding the entindex of the target so our size of the message will be 1 byte, for values that may differ insize(such as chat string) or if you don't know the size you can use -1 to have it determine the size on it's own.
Lastly to show the hud element we'll need a entry in HudLayouts.res
Which looks like this:
This finishes up the HUD side of the tracking, the next page will continue with selecting and marking players, cycling through selections and interacting with the targeted players(in my case I'm gonna teleport the marking player to the location of the marked player and the marked player to the location of the marking player) when a player activates his secondary weapon function for my custom weapon_stopwatch.
So keep on reading!