Adding New CVARs


(MessiaH) #1

Hi,

I’m working on an ET mod called “ProFrag”.
I’d like to know where you add new cvar commands so I can let the admin choose how many weapon clips each player class starts out with.

I also have some other features in my mod that I want the admin to be able to change.

Thanks.


(Lanz) #2

Look in g_main.c on line 27+ (vmCvar_t), and how to assign the cvar on line 207+.


(nUllSkillZ) #3

Thres an article at cod3arena about cvars (post: Resource: Article "Cvars, commands, and VM Communicatio):
ARTICLE 9 - Cvars, commands, and VM Communication

I also have posted a question concerning cvars:
Question: Problem with CVARS in bothgame-files

And here I’ve posted an example (at his moment last post in this thread):
[Fix] shuffle_teams: better shuffle algorithm

My tutorial also posted here isn’t good enough. I have to rewrite this. The above mentioned example is much better.


(MessiaH) #4

OK, can someone walk me through this or even show me the code for doing this.
I want to make a cvar where the admin can change the time it takes for dynamite to explode, instead of 30 seconds.

So, the admin can change the value of it, instead of being 30000.


traceEnt->nextthink = level.time + 30000;

For example:

pf_dynaTime 25000
Would change the dynamite explode time from 30 seconds to 25 seconds.

Thanks!
That would be a big help!


(bacon) #5

somewhere in g_main.c near the vmCvar_t code add

vmCvar_t pf_dynaTime;

Then down a bit you add

{ &pf_dynaTime, "pf_dynaTime", "25000",  0, 0, qtrue, qtrue },

In g_local.h near the extern vmCvar_t add

extern vmCvar_t pf_dynaTime;

THEN change

traceEnt->nextthink = level.time + 30000;

to

traceEnt->nextthink = level.time + pf_dynaTime.value;

(nUllSkillZ) #6

I’ve found this code snippet in:
file: g_weapon.c
function: Weapon_Engineer
Line: 1821

Create a varaible of type vmCvar_t:
File: “g_main.c”
Line: around 208


vmCvar_t		g_mod_dyntime;

Add a reference to the array cvarTable[]:
File: “g_main.c”
Line: around 222


	{ &g_mod_dyntime, "g_mod_dyntime", "25000", CVAR_ARCHIVE, 0, qfalse },

Remark: There are several CVAR_-constants. They are documented in the file “q_shared.h”.
I think CVAR_ARCHIVE works fine. But take a look yourself.

Remark: For cvars in the cg_ or ui_ part of the source the reference is slightly different (take a look at the article I mentioned before).

Finally you have to add a reference in the local header file:
File: “g.local.h”
Line: around 1609


extern	vmCvar_t	g_mod_dyntime;

The cvar is available through “g_mod_dyntime.integer”.
So the code you were asking for should be like:


traceEnt->nextthink = level.time + g_mod_dyntime.integer;

Note: this is only a very short version.
This should be working (if this is the only part in source which deals with the dynamite).
Please report if so. Also please report if something has to be changed.


(guerilla) #7

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.


(nUllSkillZ) #8

@guerilla:
Thanks for the info about getting access to cvars out of bg_-files.
One thing I haven’t had a clue before.