I have a working example I can show you. this is the first thing I ever did to the ET source, and I’m sorry to anyone who’s going to tell me I did it wrong, for I am ignorant and didn’t bother to research it much. I added a cvar to the game source called g_healthpackRestriction, which when enabled prevents medics from eating their own healthpacks. the first step in adding a server cvar is to declare and define it in g_main.c as such:
first, declare your cvar:
......
vmCvar_t g_nextmap;
vmCvar_t g_nextcampaign;
vmCvar_t g_disableComplaints;
// guerilla
vmCvar_t g_healthpackRestriction;
.....
next, add it to the cvar table (gameCvarTable):
......
{ &g_nextmap, "nextmap", "", CVAR_TEMP },
{ &g_nextcampaign, "nextcampaign", "", CVAR_TEMP },
{ &g_disableComplaints, "g_disableComplaints", "0", CVAR_ARCHIVE },
// guerilla
{ &g_healthpackRestriction, "g_healthpackRestriction", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse },
.......
explanation: &g_healthpackRestriction is the address of your cvar you just declared previously. the string “g_healthpackRestriction” is the cvars ‘console name’ (the way to address/change it). the string “0” is the default value, and yes, this has to be a string. CVAR_ARCHIVE and CVAR_SERVERINFO are preprocessor defines used as flags; consult q_shared.h for their meanings. always make the next field 0, it is the value that holds the number of times the cvar has changed. qfalse specifies that clients should
not recieve a text announcement when the cvar changes. if you’re interested in defining new cvars in cgame or ui instead, it’s a little different, so I’m not going to bother talking about that right now.
after this is done, you should also declare your new cvar in g_local.h like so:
extern vmCvar_t bot_debug_cover_spot; // What cover spot are we going to?
extern vmCvar_t bot_debug_anim; // what animation is the bot playing?
// guerilla
extern vmCvar_t g_healthpackRestriction;
it’s all just child’s play really. just mimic the other cvars. as for accessing the cvar, you have to implement it differently for game/cgame. let me post my code from BG_CanItemBeGrabbed()
case IT_HEALTH:
// Gordon: ps->teamNum is really class.... thx whoever decided on that...
if( ps->teamNum == PC_MEDIC ) {
// guerilla: code to implement medic health pack restrictions
#if defined(CGAMEDLL) || defined (GAMEDLL)
const char *info, *s;
int value;
#ifdef CGAMEDLL
info = CG_ConfigString(CS_SERVERINFO);
s = Info_ValueForKey(info, "g_healthpackRestriction");
if (s)
value = atoi(s);
#elif GAMEDLL
value = g_healthPackRestriction.integer;
#endif
if (value)
if (ent->clientNum == ps->clientNum)
return qfalse;
#endif
the import thing to note is how you access a cvar differently depending on if you are compiling for game/cgame. in game it’s cake, just the name of the cvar. in cgame, you have to do a little song-and-dance to get the value. if you don’t have to worry about client-side prediction, don’t even worry about accessing server cvars from cgame. in your case, you’d want to do
traceEnt->nextthink = level.time + pf_dynaTime.integer;
if in your case you have to worry about prediction, just look at what I did, you’ll figure it out.