From 220e346d79355e818015a983f55a48190184a784 Mon Sep 17 00:00:00 2001 From: Tim Angus Date: Tue, 29 Nov 2005 23:46:54 +0000 Subject: * Lowered steptime for spectator * Added worldspawn keys to disable specific game elements --- src/game/bg_misc.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/game/bg_public.h | 5 ++ src/game/g_active.c | 2 +- src/game/g_cmds.c | 40 ++++++------ src/game/g_local.h | 9 +++ src/game/g_main.c | 115 +++++++++++++++++++++++++++++++++++ src/game/g_spawn.c | 31 +++++----- src/game/g_trigger.c | 123 +++---------------------------------- 8 files changed, 338 insertions(+), 154 deletions(-) (limited to 'src/game') diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c index 579137fe..4fc2ffc0 100644 --- a/src/game/bg_misc.c +++ b/src/game/bg_misc.c @@ -1474,7 +1474,7 @@ classAttributes_t bg_classList[ ] = 90, //int fov; 0.000f, //float bob; 1.0f, //float bobCycle; - 350, //int steptime; + 0, //int steptime; 600, //float speed; 10.0f, //float acceleration; 1.0f, //float airAcceleration; @@ -5081,3 +5081,168 @@ int atoi_neg( char *token, qboolean allowNegative ) return value; } + +/* +=============== +BG_ParseCSVEquipmentList +=============== +*/ +void BG_ParseCSVEquipmentList( const char *string, weapon_t *weapons, int weaponsSize, + upgrade_t *upgrades, int upgradesSize ) +{ + char buffer[ MAX_STRING_CHARS ]; + int i = 0, j = 0; + char *p, *q; + qboolean EOS = qfalse; + + Q_strncpyz( buffer, string, MAX_STRING_CHARS ); + + p = q = buffer; + + while( *p != '\0' ) + { + //skip to first , or EOS + while( *p != ',' && *p != '\0' ) + p++; + + if( *p == '\0' ) + EOS = qtrue; + + *p = '\0'; + + //strip leading whitespace + while( *q == ' ' ) + q++; + + if( weaponsSize ) + weapons[ i ] = BG_FindWeaponNumForName( q ); + + if( upgradesSize ) + upgrades[ j ] = BG_FindUpgradeNumForName( q ); + + if( weaponsSize && weapons[ i ] == WP_NONE && + upgradesSize && upgrades[ j ] == UP_NONE ) + Com_Printf( S_COLOR_YELLOW "WARNING: unknown equipment %s\n", q ); + else if( weaponsSize && weapons[ i ] != WP_NONE ) + i++; + else if( upgradesSize && upgrades[ j ] != UP_NONE ) + j++; + + if( !EOS ) + { + p++; + q = p; + } + else + break; + + if( i == ( weaponsSize - 1 ) || j == ( upgradesSize - 1 ) ) + break; + } + + if( weaponsSize ) + weapons[ i ] = WP_NONE; + + if( upgradesSize ) + upgrades[ j ] = UP_NONE; +} + +/* +=============== +BG_ParseCSVClassList +=============== +*/ +void BG_ParseCSVClassList( const char *string, pClass_t *classes, int classesSize ) +{ + char buffer[ MAX_STRING_CHARS ]; + int i = 0; + char *p, *q; + qboolean EOS = qfalse; + + Q_strncpyz( buffer, string, MAX_STRING_CHARS ); + + p = q = buffer; + + while( *p != '\0' ) + { + //skip to first , or EOS + while( *p != ',' && *p != '\0' ) + p++; + + if( *p == '\0' ) + EOS = qtrue; + + *p = '\0'; + + //strip leading whitespace + while( *q == ' ' ) + q++; + + classes[ i ] = BG_FindClassNumForName( q ); + + if( classes[ i ] == PCL_NONE ) + Com_Printf( S_COLOR_YELLOW "WARNING: unknown class %s\n", q ); + else + i++; + + if( !EOS ) + { + p++; + q = p; + } + else + break; + } + + classes[ i ] = PCL_NONE; +} + +/* +=============== +BG_ParseCSVBuildableList +=============== +*/ +void BG_ParseCSVBuildableList( const char *string, buildable_t *buildables, int buildablesSize ) +{ + char buffer[ MAX_STRING_CHARS ]; + int i = 0; + char *p, *q; + qboolean EOS = qfalse; + + Q_strncpyz( buffer, string, MAX_STRING_CHARS ); + + p = q = buffer; + + while( *p != '\0' ) + { + //skip to first , or EOS + while( *p != ',' && *p != '\0' ) + p++; + + if( *p == '\0' ) + EOS = qtrue; + + *p = '\0'; + + //strip leading whitespace + while( *q == ' ' ) + q++; + + buildables[ i ] = BG_FindClassNumForName( q ); + + if( buildables[ i ] == BA_NONE ) + Com_Printf( S_COLOR_YELLOW "WARNING: unknown buildable %s\n", q ); + else + i++; + + if( !EOS ) + { + p++; + q = p; + } + else + break; + } + + buildables[ i ] = BA_NONE; +} diff --git a/src/game/bg_public.h b/src/game/bg_public.h index 5cc157e4..25f5a90d 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -1291,3 +1291,8 @@ float round( float v ); float atof_neg( char *token, qboolean allowNegative ); int atoi_neg( char *token, qboolean allowNegative ); + +void BG_ParseCSVEquipmentList( const char *string, weapon_t *weapons, int weaponsSize, + upgrade_t *upgrades, int upgradesSize ); +void BG_ParseCSVClassList( const char *string, pClass_t *classes, int classesSize ); +void BG_ParseCSVBuildableList( const char *string, buildable_t *buildables, int buildablesSize ); diff --git a/src/game/g_active.c b/src/game/g_active.c index 846397db..54ae33e8 100644 --- a/src/game/g_active.c +++ b/src/game/g_active.c @@ -1322,7 +1322,7 @@ void ClientThink_real( gentity_t *ent ) { if( BG_ClassCanEvolveFromTo( client->ps.stats[ STAT_PCLASS ], j, client->ps.persistant[ PERS_CREDIT ], 0 ) >= 0 && - BG_FindStagesForClass( j, g_alienStage.integer ) ) + BG_FindStagesForClass( j, g_alienStage.integer ) && G_ClassIsAllowed( j ) ) { upgrade = qtrue; break; diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 4491cd77..540bedd0 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -1114,19 +1114,15 @@ void Cmd_Class_f( gentity_t *ent ) clientNum = ent->client - level.clients; trap_Argv( 1, s, sizeof( s ) ); - if( BG_FindStagesForClass( PCL_ALIEN_BUILDER0_UPG, g_alienStage.integer ) ) - { - allowedClasses[ 0 ] = PCL_ALIEN_BUILDER0; - allowedClasses[ 1 ] = PCL_ALIEN_BUILDER0_UPG; - allowedClasses[ 2 ] = PCL_ALIEN_LEVEL0; - numClasses = 3; - } - else - { - allowedClasses[ 0 ] = PCL_ALIEN_BUILDER0; - allowedClasses[ 1 ] = PCL_ALIEN_LEVEL0; - numClasses = 2; - } + if( G_ClassIsAllowed( PCL_ALIEN_BUILDER0 ) ) + allowedClasses[ numClasses++ ] = PCL_ALIEN_BUILDER0; + + if( G_ClassIsAllowed( PCL_ALIEN_BUILDER0_UPG ) && + BG_FindStagesForClass( PCL_ALIEN_BUILDER0_UPG, g_alienStage.integer ) ) + allowedClasses[ numClasses++ ] = PCL_ALIEN_BUILDER0; + + if( G_ClassIsAllowed( PCL_ALIEN_LEVEL0 ) ) + allowedClasses[ numClasses++ ] = PCL_ALIEN_LEVEL0; if( ent->client->pers.teamSelection == PTE_ALIENS && !( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) && @@ -1211,7 +1207,9 @@ void Cmd_Class_f( gentity_t *ent ) if( !tr.startsolid && tr2.fraction == 1.0f ) { //...check we can evolve to that class - if( numLevels >= 0 && BG_FindStagesForClass( ent->client->pers.classSelection, g_alienStage.integer ) ) + if( numLevels >= 0 && + BG_FindStagesForClass( ent->client->pers.classSelection, g_alienStage.integer ) && + G_ClassIsAllowed( ent->client->pers.classSelection ) ) { ent->client->pers.evolveHealthFraction = (float)ent->client->ps.stats[ STAT_HEALTH ] / (float)BG_FindHealthForClass( currentClass ); @@ -1255,7 +1253,8 @@ void Cmd_Class_f( gentity_t *ent ) for( i = 0; i < numClasses; i++ ) { if( allowedClasses[ i ] == ent->client->pers.classSelection && - BG_FindStagesForClass( ent->client->pers.classSelection, g_alienStage.integer ) ) + BG_FindStagesForClass( ent->client->pers.classSelection, g_alienStage.integer ) && + G_ClassIsAllowed( ent->client->pers.classSelection ) ) { G_PushSpawnQueue( &level.alienSpawnQueue, clientNum ); return; @@ -1285,11 +1284,11 @@ void Cmd_Class_f( gentity_t *ent ) ent->client->ps.stats[ STAT_PCLASS ] = PCL_HUMAN; //set the item to spawn with - if( !Q_stricmp( s, BG_FindNameForWeapon( WP_MACHINEGUN ) ) ) + if( !Q_stricmp( s, BG_FindNameForWeapon( WP_MACHINEGUN ) ) && G_WeaponIsAllowed( WP_MACHINEGUN ) ) ent->client->pers.humanItemSelection = WP_MACHINEGUN; - else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD ) ) ) + else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD ) ) && G_WeaponIsAllowed( WP_HBUILD ) ) ent->client->pers.humanItemSelection = WP_HBUILD; - else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD2 ) ) && + else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD2 ) ) && G_WeaponIsAllowed( WP_HBUILD2 ) && BG_FindStagesForWeapon( WP_HBUILD2, g_humanStage.integer ) ) ent->client->pers.humanItemSelection = WP_HBUILD2; else @@ -1563,7 +1562,7 @@ void Cmd_Buy_f( gentity_t *ent ) } //are we /allowed/ to buy this? - if( !BG_FindStagesForWeapon( weapon, g_humanStage.integer ) ) + if( !BG_FindStagesForWeapon( weapon, g_humanStage.integer ) || !G_WeaponIsAllowed( weapon ) ) { G_SendCommandFromServer( ent-g_entities, va( "print \"You can't buy this item\n\"" ) ); return; @@ -1626,7 +1625,7 @@ void Cmd_Buy_f( gentity_t *ent ) } //are we /allowed/ to buy this? - if( !BG_FindStagesForUpgrade( upgrade, g_humanStage.integer ) ) + if( !BG_FindStagesForUpgrade( upgrade, g_humanStage.integer ) || !G_UpgradeIsAllowed( upgrade ) ) { G_SendCommandFromServer( ent-g_entities, va( "print \"You can't buy this item\n\"" ) ); return; @@ -1838,6 +1837,7 @@ void Cmd_Build_f( gentity_t *ent ) ( ( 1 << ent->client->ps.weapon ) & BG_FindBuildWeaponForBuildable( buildable ) ) && !( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) && !( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) && + G_BuildableIsAllowed( buildable ) && ( ( team == PTE_ALIENS && BG_FindStagesForBuildable( buildable, g_alienStage.integer ) ) || ( team == PTE_HUMANS && BG_FindStagesForBuildable( buildable, g_humanStage.integer ) ) ) ) { diff --git a/src/game/g_local.h b/src/game/g_local.h index a7078ace..002d4cb5 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -877,6 +877,11 @@ void SendScoreboardMessageToAllClients( void ); void QDECL G_Printf( const char *fmt, ... ); void QDECL G_Error( const char *fmt, ... ); +qboolean G_WeaponIsAllowed( weapon_t weapon ); +qboolean G_UpgradeIsAllowed( upgrade_t upgrade ); +qboolean G_ClassIsAllowed( pClass_t class ); +qboolean G_BuildableIsAllowed( buildable_t buildable ); + // // g_client.c // @@ -1069,6 +1074,10 @@ extern vmCvar_t g_alienMaxStage; extern vmCvar_t g_alienStage2Threshold; extern vmCvar_t g_alienStage3Threshold; +extern vmCvar_t g_disabledEquipment; +extern vmCvar_t g_disabledClasses; +extern vmCvar_t g_disabledBuildables; + extern vmCvar_t g_debugMapRotation; extern vmCvar_t g_currentMapRotation; extern vmCvar_t g_currentMap; diff --git a/src/game/g_main.c b/src/game/g_main.c index 8ae93622..1afb6744 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -90,6 +90,10 @@ vmCvar_t g_alienMaxStage; vmCvar_t g_alienStage2Threshold; vmCvar_t g_alienStage3Threshold; +vmCvar_t g_disabledEquipment; +vmCvar_t g_disabledClasses; +vmCvar_t g_disabledBuildables; + vmCvar_t g_debugMapRotation; vmCvar_t g_currentMapRotation; vmCvar_t g_currentMap; @@ -174,6 +178,10 @@ static cvarTable_t gameCvarTable[ ] = { &g_alienStage2Threshold, "g_alienStage2Threshold", "20", 0, 0, qfalse }, { &g_alienStage3Threshold, "g_alienStage3Threshold", "40", 0, 0, qfalse }, + { &g_disabledEquipment, "g_disabledEquipment", "", CVAR_ROM, 0, qfalse }, + { &g_disabledClasses, "g_disabledClasses", "", CVAR_ROM, 0, qfalse }, + { &g_disabledBuildables, "g_disabledBuildables", "", CVAR_ROM, 0, qfalse }, + { &g_debugMapRotation, "g_debugMapRotation", "0", 0, 0, qfalse }, { &g_currentMapRotation, "g_currentMapRotation", "-1", 0, 0, qfalse }, // -1 = NOT_ROTATING { &g_currentMap, "g_currentMap", "0", 0, 0, qfalse }, @@ -446,6 +454,110 @@ static void G_GenerateParticleFileList( void ) } } +typedef struct gameElements_s +{ + buildable_t buildables[ BA_NUM_BUILDABLES ]; + pClass_t classes[ PCL_NUM_CLASSES ]; + weapon_t weapons[ WP_NUM_WEAPONS ]; + upgrade_t upgrades[ UP_NUM_UPGRADES ]; +} gameElements_t; + +static gameElements_t disabledGameElements; + +/* +============ +G_InitAllowedGameElements +============ +*/ +static void G_InitAllowedGameElements( void ) +{ + BG_ParseCSVEquipmentList( g_disabledEquipment.string, + disabledGameElements.weapons, WP_NUM_WEAPONS, + disabledGameElements.upgrades, UP_NUM_UPGRADES ); + + BG_ParseCSVClassList( g_disabledClasses.string, + disabledGameElements.classes, PCL_NUM_CLASSES ); + + BG_ParseCSVBuildableList( g_disabledBuildables.string, + disabledGameElements.buildables, BA_NUM_BUILDABLES ); +} + +/* +============ +G_WeaponIsAllowed +============ +*/ +qboolean G_WeaponIsAllowed( weapon_t weapon ) +{ + int i; + + for( i = 0; i < WP_NUM_WEAPONS && + disabledGameElements.weapons[ i ] != WP_NONE; i++ ) + { + if( disabledGameElements.weapons[ i ] == weapon ) + return qfalse; + } + + return qtrue; +} + +/* +============ +G_UpgradeIsAllowed +============ +*/ +qboolean G_UpgradeIsAllowed( upgrade_t upgrade ) +{ + int i; + + for( i = 0; i < UP_NUM_UPGRADES && + disabledGameElements.upgrades[ i ] != UP_NONE; i++ ) + { + if( disabledGameElements.upgrades[ i ] == upgrade ) + return qfalse; + } + + return qtrue; +} + +/* +============ +G_ClassIsAllowed +============ +*/ +qboolean G_ClassIsAllowed( pClass_t class ) +{ + int i; + + for( i = 0; i < PCL_NUM_CLASSES && + disabledGameElements.classes[ i ] != PCL_NONE; i++ ) + { + if( disabledGameElements.classes[ i ] == class ) + return qfalse; + } + + return qtrue; +} + +/* +============ +G_BuildableIsAllowed +============ +*/ +qboolean G_BuildableIsAllowed( buildable_t buildable ) +{ + int i; + + for( i = 0; i < BA_NUM_BUILDABLES && + disabledGameElements.buildables[ i ] != BA_NONE; i++ ) + { + if( disabledGameElements.buildables[ i ] == buildable ) + return qfalse; + } + + return qtrue; +} + /* ============ G_InitGame @@ -526,6 +638,9 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) // parse the key/value pairs and spawn gentities G_SpawnEntitiesFromString( ); + // the map might disable some things + G_InitAllowedGameElements( ); + // general initialization G_FindTeams( ); diff --git a/src/game/g_spawn.c b/src/game/g_spawn.c index 2c279757..39db22be 100644 --- a/src/game/g_spawn.c +++ b/src/game/g_spawn.c @@ -318,24 +318,14 @@ qboolean G_CallSpawn( gentity_t *ent ) //check buildable spawn functions if( ( buildable = BG_FindBuildNumForEntityName( ent->classname ) ) != BA_NONE ) { - /*if( BG_FindStagesForBuildable( buildable, 1 ) )*/ - if( qtrue ) + if( buildable == BA_A_SPAWN || buildable == BA_H_SPAWN ) { - if( buildable == BA_A_SPAWN || buildable == BA_H_SPAWN ) - { - ent->s.angles[ YAW ] += 180.0f; - AngleNormalize360( ent->s.angles[ YAW ] ); - } - - G_SpawnBuildable( ent, buildable ); - return qtrue; - } - else - { - G_Printf( S_COLOR_YELLOW "WARNING: %s not allowed in stage 1\n", - BG_FindHumanNameForBuildable( buildable ) ); - return qfalse; + ent->s.angles[ YAW ] += 180.0f; + AngleNormalize360( ent->s.angles[ YAW ] ); } + + G_SpawnBuildable( ent, buildable ); + return qtrue; } // check normal spawn functions @@ -647,6 +637,15 @@ void SP_worldspawn( void ) G_SpawnString( "enableBreath", "0", &s ); trap_Cvar_Set( "g_enableBreath", s ); + G_SpawnString( "disabledEquipment", "", &s ); + trap_Cvar_Set( "g_disabledEquipment", s ); + + G_SpawnString( "disabledClasses", "", &s ); + trap_Cvar_Set( "g_disabledClasses", s ); + + G_SpawnString( "disabledBuildables", "", &s ); + trap_Cvar_Set( "g_disabledBuildables", s ); + g_entities[ ENTITYNUM_WORLD ].s.number = ENTITYNUM_WORLD; g_entities[ ENTITYNUM_WORLD ].classname = "worldspawn"; diff --git a/src/game/g_trigger.c b/src/game/g_trigger.c index e928cc69..d92e44b4 100644 --- a/src/game/g_trigger.c +++ b/src/game/g_trigger.c @@ -617,10 +617,7 @@ SP_trigger_buildable */ void SP_trigger_buildable( gentity_t *self ) { - char *buffer; - int i = 0; - char *p, *q; - qboolean EOS = qfalse; + char *buffer; G_SpawnFloat( "wait", "0.5", &self->wait ); G_SpawnFloat( "random", "0", &self->random ); @@ -633,39 +630,7 @@ void SP_trigger_buildable( gentity_t *self ) G_SpawnString( "buildables", "", &buffer ); - p = q = buffer; - - while( *p != '\0' ) - { - //skip to first , or EOS - while( *p != ',' && *p != '\0' ) - p++; - - if( *p == '\0' ) - EOS = qtrue; - - *p = '\0'; - - //strip leading whitespace - while( *q == ' ' ) - q++; - - self->bTriggers[ i ] = BG_FindBuildNumForName( q ); - if( self->bTriggers[ i ] == BA_NONE ) - G_Printf( S_COLOR_YELLOW "WARNING: unknown buildable %s in trigger_buildable\n", q ); - else - i++; - - if( !EOS ) - { - p++; - q = p; - } - else - break; - } - - self->bTriggers[ i ] = BA_NONE; + BG_ParseCSVBuildableList( buffer, self->bTriggers, BA_NUM_BUILDABLES ); self->touch = trigger_buildable_touch; self->use = trigger_buildable_use; @@ -757,10 +722,7 @@ SP_trigger_class */ void SP_trigger_class( gentity_t *self ) { - char *buffer; - int i = 0; - char *p, *q; - qboolean EOS = qfalse; + char *buffer; G_SpawnFloat( "wait", "0.5", &self->wait ); G_SpawnFloat( "random", "0", &self->random ); @@ -773,39 +735,7 @@ void SP_trigger_class( gentity_t *self ) G_SpawnString( "classes", "", &buffer ); - p = q = buffer; - - while( *p != '\0' ) - { - //skip to first , or EOS - while( *p != ',' && *p != '\0' ) - p++; - - if( *p == '\0' ) - EOS = qtrue; - - *p = '\0'; - - //strip leading whitespace - while( *q == ' ' ) - q++; - - self->cTriggers[ i ] = BG_FindClassNumForName( q ); - if( self->cTriggers[ i ] == PCL_NONE ) - G_Printf( S_COLOR_YELLOW "WARNING: unknown class %s in trigger_class\n", q ); - else - i++; - - if( !EOS ) - { - p++; - q = p; - } - else - break; - } - - self->cTriggers[ i ] = PCL_NONE; + BG_ParseCSVClassList( buffer, self->cTriggers, PCL_NUM_CLASSES ); self->touch = trigger_class_touch; self->use = trigger_class_use; @@ -906,10 +836,7 @@ SP_trigger_equipment */ void SP_trigger_equipment( gentity_t *self ) { - char *buffer; - int i = 0, j = 0; - char *p, *q; - qboolean EOS = qfalse; + char *buffer; G_SpawnFloat( "wait", "0.5", &self->wait ); G_SpawnFloat( "random", "0", &self->random ); @@ -922,44 +849,8 @@ void SP_trigger_equipment( gentity_t *self ) G_SpawnString( "equipment", "", &buffer ); - p = q = buffer; - - while( *p != '\0' ) - { - //skip to first , or EOS - while( *p != ',' && *p != '\0' ) - p++; - - if( *p == '\0' ) - EOS = qtrue; - - *p = '\0'; - - //strip leading whitespace - while( *q == ' ' ) - q++; - - self->wTriggers[ i ] = BG_FindWeaponNumForName( q ); - self->uTriggers[ j ] = BG_FindUpgradeNumForName( q ); - - if( self->wTriggers[ i ] == WP_NONE && self->uTriggers[ j ] == UP_NONE ) - G_Printf( S_COLOR_YELLOW "WARNING: unknown equipment %s in trigger_class\n", q ); - else if( self->wTriggers[ i ] != WP_NONE ) - i++; - else if( self->uTriggers[ j ] != UP_NONE ) - j++; - - if( !EOS ) - { - p++; - q = p; - } - else - break; - } - - self->wTriggers[ i ] = WP_NONE; - self->uTriggers[ j ] = UP_NONE; + BG_ParseCSVEquipmentList( buffer, self->wTriggers, WP_NUM_WEAPONS, + self->uTriggers, UP_NUM_UPGRADES ); self->touch = trigger_equipment_touch; self->use = trigger_equipment_use; -- cgit