Disabling Items


First off, please let me know if you use this tutorial and it works for you, as Its purely theoretical at the moment (I can't test it yet) [This message will be removed as soon as I get confirmation that this works]

Anyway, There was a request on the qdevels board(or the pq mailing list, I can't remember which] for a tutorial about disabling the items that are on the map to start with. This didn't seem too hard (it's really easy with q2) to I thought I'd try doing it. Here's my attempt at doing so.


Find G_CallSpawn (in g_spawn.c [game]). You should note that it tries finding an entity in the item list first, before trying to find it in the normal spawn funtions. This makes life really easy. (and the fact it shows how to disable team only items for non team games makes life even easier)

find the code below.

if( item->giType == IT_TEAM && g_gametype.integer != GT_CTF ) {
			return qfalse;
			}
			G_SpawnItem( ent, item );
			return qtrue;

Now, there are two ways to disable the items, just always return qfalse (breaks ctf), or check the flags and only return qfalse in some situations. I'm going to take the second route, and split it off into another function. makes the code neater, and easier to read. Change the code above, to the code below

if( !S_CheckItem(item) ) 
	{
		return qfalse;
	}
	G_SpawnItem( ent, item );
	return qtrue;

I know that S_CheckItem could just return the other value, but this could end up being a generic check routine (i have some plans) so I'm keeping it as returning true if the item is to be spawned


anyway, copy the function below above G_CallSpawn (or stick it in a new file with a #include g_local.h with a protoype in g_spawn.c). I'll explain anything that needs it after the function

qboolean S_CheckItem(gitem_t *checkeditem)
{


switch (checkeditem->giType)
{
case IT_WEAPON:
	return qtrue;
case IT_AMMO:
	return qtrue;
case IT_ARMOR:
	return qtrue;
case IT_HEALTH:
	return qtrue;
case IT_POWERUP:
	return qtrue;
case IT_HOLDABLE:
	return qtrue;
case IT_TEAM:
	if (g_gametype.integer == GT_CTF)
		return qtrue;
}
return qfalse;
}

Ok, fairly simple function, right? If you want to disable an item type, then just change the qtrue to a qfalse under the relevent case statment. Why am I passing the full item type? So you can do specific weapon and item checks. You don't like the railgun? Easy to remove without touching the other weapons. Just add the code below, just before the switch statement. (modify it for other items. Remember to use the actual classname rather than the pickup name. Look in bg_misc.c [game] for the item list. )

if (!strcmp(checkeditem->classname,"weapon_railgun"))
	return qfalse;

Easy, right? the !is there because strcmp returns 0 if they are equal and 1 if they are not ( I don't know why, but thats life)


One final addition. If you've implemented new cvars (server side) [see this turorial for instructions on how to do this] Then it's simple to change the check function to use them to disable specific items and classes of items on a game by game basis. For the classes of items add a check within the case (example below)

case IT_WEAPON:
if (s_disableweapons.integer==1)
	return qfalse;
else
return qtrue;

if you want to disable individual items by cvars, then it just requires a slight modification of the basic item removal. See below for an example

if (!strcmp(checkeditem->classname,"weapon_railgun") && (s_disablerailgun == 1))
	return qfalse;

Note: if you want to disable all but one weapon, then follow the instructions for disabling a single item, but change the return value to qtrue, while changeing the value for all the other weapons to qfalse


Back to the tutorial page
Mail Me