Jump to content

Home

Breaking the 16 weapon limit


keo718

Recommended Posts

I found this in a Quake3 forum....

 

-------

The weapon system in baseq3 works using an index in the ent->client->ps.stats array - STAT_WEAPONS. This is a bit list of weapons that the client currently holds, corresponding to the weapon_t enumeration. The maximum weapons count is limited to 16 since only 16 bits of an int are communicated across the network via the stats array.

 

Using lots of bitwise operators, it's relatively straight forward to remove this limit. Add another indice to the statIndex_t enumeration called STAT_WEAPONS2. This will simply serve as an extenstion of STAT_WEAPONS raising the weapon limit to 32.

 

Use the following functions (placed in bg_misc.c) to alter and query these two STAT_ indices:

 

 

code:

--------------------------------------------------------------------------------

 

//TA: pack weapons into the arrayvoid BG_packWeapon( int weapon, int stats[ ] ){ int weaponList; weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 ); weaponList |= ( 1 << weapon ); stats[ STAT_WEAPONS ] = weaponList & 0x0000FFFF; stats[ STAT_WEAPONS2 ] = ( weaponList & 0xFFFF0000 ) >> 16;}//TA: remove weapons from the arrayvoid BG_removeWeapon( int weapon, int stats[ ] ){ int weaponList; weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 ); weaponList &= ~( 1 << weapon ); stats[ STAT_WEAPONS ] = weaponList & 0x0000FFFF; stats[ STAT_WEAPONS2 ] = ( weaponList & 0xFFFF0000 ) >> 16;}//TA: check whether array contains weaponqboolean BG_gotWeapon( int weapon, int stats[ ] ){ int weaponList; weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 ); return( weaponList & ( 1 << weapon ) );}

 

--------------------------------------------------------------------------------

 

You must then trawl through the codebase changing each modification or check of weapons with the equivalent function call above.

 

For example:

 

 

code:

--------------------------------------------------------------------------------

 

client->ps.stats[sTAT_WEAPONS] = ( 1 << WP_MACHINEGUN );

 

--------------------------------------------------------------------------------

 

 

in g_client.c becomes

 

code:

--------------------------------------------------------------------------------

 

BG_packWeapon( WP_MACHINEGUN, client->ps.stats );

 

--------------------------------------------------------------------------------

 

and

 

 

code:

--------------------------------------------------------------------------------

 

if ( client->ps.stats[sTAT_WEAPONS] & ( 1 << i ) ) {

 

--------------------------------------------------------------------------------

 

 

also in g_client.c becomes

 

code:

--------------------------------------------------------------------------------

 

if( BG_gotWeapon( i, client->ps.stats ) ) {

 

--------------------------------------------------------------------------------

 

You get the idea.

 

That is not the end of the problems however. You must also store ammo for each weapon. This varies from modification to modification however, depending on whether many weapons share ammo and clip based systems. This is a solution which uses the powerups array as well as the ammo array to store ammo quantities using bit packing to store clips (if the weapons are clip based):

 

 

code:

--------------------------------------------------------------------------------

 

//TA: extract the ammo quantity from the arrayvoid BG_unpackAmmoArray( int weapon, int ammo[ ], int ammo2[ ], int *quan, int *clips, int *maxclips ){ int ammoarray[32]; int i; for( i = 0; i <= 15; i++ ) ammoarray[ i ] = ammo[ i ]; for( i = 16; i <= 31; i++ ) ammoarray[ i ] = ammo2[ i - 16 ]; if( quan != NULL ) *quan = ammoarray[ weapon ] & 0x03FF; if( clips != NULL ) *clips = ( ammoarray[ weapon ] >> 10 ) & 0x07; if( maxclips != NULL ) *maxclips = ( ammoarray[ weapon ] >> 13 ) & 0x07;} //TA: pack the ammo quantity into the arrayvoid BG_packAmmoArray( int weapon, int ammo[ ], int ammo2[ ], int quan, int clips, int maxclips ){ int weaponvalue; weaponvalue = quan | ( clips << 10 ) | ( maxclips << 13 ); if( weapon <= 15 ) ammo[ weapon ] = weaponvalue; else if( weapon >= 16 ) ammo2[ weapon - 16 ] = weaponvalue;}

 

--------------------------------------------------------------------------------

 

Please bear in mind you must sacrifice the powerups array (and hence all powerups) to use this method. An alternative is to split each indice of the ammo array into two 8 bit numbers, so that the ammo array stores 32 numbers total. This limits your maximum ammo value to 255 however.

Link to comment
Share on other sites

that's the info i referred to through all this time.

It states the limitations at the bottom. And as I said, they apply only if there's more than 16 types of ammo.

 

Could you give me a link there? I forgot it.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...