
Quake DeveLS - Radio
Author: Xaos
Difficulty: Easy
NOTE: The file radio.zip
must be downloaded in order for this tutorial to work! I have included sample
wav files in a pak file as well as a sample chat config script to use it.
Preamble
--------
You're a Space Marine,
right? RIGHT!
Space Marines have radios,
right? RIGHT!
Here is a modification
which will allow you to use your radio to "chat" with the other
Marines. Using pre-recorded messages, you will actually be able to hear what
others have to say.
First, create a file
called "x_radio.h" in your Quake 2 DLL project workspace. Into this,
put the following lines of code :
// radio functions
void X_Radio_Power_f(edict_t *self, char *state);
void X_Radio_f(edict_t *self, char *channel, char *msg);
Explanation : These lines of code are the function prototypes. I find it nice
to keep as much of my code as possible in separate files so that I don't muck
up the original code much. I'll explain these functions later on in the
tutorial.
Next insert the following
code at the end of the "client_persistant_t" structure in
"g_local.h" (about line 836)
//======================================================== //XAOS Radio Code //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv int radio_power; //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Explanation : This will hold the status for the radio in the clients structure.
Setting it to 1 allows the player to hear messages while setting it to 0
disables all message reception for that player.
Next insert the following
code at end of qboolean ClientConnect (edict_t *ent, char *userinfo) before
ClientUserinfoChanged (ent, userinfo) in "p_client.c" (about line
1383)
//======================================================== //XAOS Initialize Radio Power Switch to OFF //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv ent->client->pers.radio_power = 0; //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Explanation : This initializes the Radio in the OFF state when the Client first
connects to the server. I decided to set it to OFF first since not everyone
will want to hear the chatter. Those that do can simply turn it back on in
their autoexec.cfg.
Now we are going to setup
the commands which you can use to turn your radio on and off as well as send
messages.
Insert the following code
at beginning of "g_cmds.c"
//======================================================== //XAOS Added include file //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv #include "x_radio.h" //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
And the foloowing at the
end of void ClientCommand (edict_t *ent) [At the end of the file]
//======================================================== //XAOS Radio Code //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvelse if (Q_stricmp (cmd, "radio_power") == 0) //Radio Power Switch
X_Radio_Power_f(ent, gi.argv(1));else if (Q_stricmp (cmd, "radio") == 0) //Radio to All Players
X_Radio_f(ent, 'ALL', gi.argv(1));else if (Q_stricmp (cmd, "tradio") == 0) //Radio to Team
X_Radio_f(ent, 'TEAM', gi.argv(1)); //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Explanation : This sets up 3 new commands.
radio_power
[0/1]
This turns the radio ON(1) or OFF(0)
radio
"wavfile"
This plays "wavfile" on all players radios who
have them turned ON
tradio
"wavfile"
This plays "wavfile" on all teammates (CTF only)
radios who have them turned ON
Now to the heart of the
radio code. Place the following into a new file called "x_radio.c" in
your Quake 2 DLL project workspace.
#include "g_local.h"
#include "q_devels.h"
#include "x_radio.h"
void X_Radio_Power_f(edict_t *self, char *state)
{ if (Q_stricmp (state, "1") == 0) { self->client->pers.radio_power = 1; gi.cprintf(self, PRINT_HIGH, "Radio ON\n"); } else { self->client->pers.radio_power = 0; gi.cprintf(self, PRINT_HIGH, "Radio OFF\n"); }}
void X_Radio_f(edict_t *self, char *channel, char *msg)
{ edict_t *player; int i; char *cmd, *pos; cmd = "\0"; // Initialize cmd variable
if(pos = strstr(msg,";")) // Check if msg contains ';'
pos[0]=0; // If so, terminate string there
sprintf( cmd, "play radio/%s\n", msg); // Build command to send
if (Q_stricmp (channel, "ALL") == 0) // To All Players
{ for_each_player(player, i) { if (player->client->pers.radio_power) x_stuffcmd(player, cmd); } }else if (Q_stricmp (channel, "TEAM") == 0) // To Team Members
{ for_each_player(player, i) { if (player->client->resp.ctf_team == self->client->resp.ctf_team) if (player->client->pers.radio_power) x_stuffcmd(player, cmd); } }}
Explanation:
X_Radio_Power_f sets the variable we added to the persistent client data
earlier and prints a message to the console to indicate the changed status.
X_Radio_f first searches
the message string for any ';'s and if it finds any, it terminates the string
at that point. This has to be done to keep players from sending additional
commends to other players' consoles (e.g. 'kill'). It then builds up the
command string to send to the other players. By building it like this, we can
limit the possible wave files to ones in the baseq2/sound/radio sub-directory.
We then check to see which
players we need to send the message to. The message is sent by using the
stuffcmd (renamed to x_stuffcmd so that it doesn't conflict with Zoid's CTF II
function) function as defined in q_devels.c (renamed here as well). This
actually sends the command to play the wavefile to another players console
instead of burdening the network with transferring the massive amounts of data
that actuall voice transmission would require.
And that's
about it ! :) The only thing left is for you to bind "radio_power" to
a suitable key, set up your aliases to play the wav files, and boot-up Quake 2
!!
There are loads of
possibilities for further modifications :
1) Implement channels so that you can have subdivisions on a team (e.g. channel 15 = Blue team defense, 16 = Blue team offense) 2) Send to a specific player. (e.g. pradio "player_name" "wavfile" ) 3) Send to a the last player to hurt you (your enemy). (e.g. eradio "wavfile" )
I'd like to thank Kevin for his assistance on plugging the
security hole which would allow additional commands to be sent to other
clients. I'd also like to thank the team that helped beta test this mod at or
last Quakefest. Thanks guys!!
Enjoy !
Tutorial by Xaos .
|
This site, and all
content and graphics displayed on it, |