diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cgame/cg_draw.c | 5 | ||||
-rw-r--r-- | src/cgame/cg_local.h | 6 | ||||
-rw-r--r-- | src/cgame/cg_servercmds.c | 11 | ||||
-rw-r--r-- | src/game/bg_public.h | 6 | ||||
-rw-r--r-- | src/game/g_active.c | 6 | ||||
-rw-r--r-- | src/game/g_buildable.c | 261 | ||||
-rw-r--r-- | src/game/g_local.h | 25 | ||||
-rw-r--r-- | src/game/g_main.c | 140 | ||||
-rw-r--r-- | src/game/tremulous.h | 7 |
9 files changed, 349 insertions, 118 deletions
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c index e30eed48..b12174f2 100644 --- a/src/cgame/cg_draw.c +++ b/src/cgame/cg_draw.c @@ -630,11 +630,8 @@ static void CG_DrawPlayerAmmoValue( rectDef_t *rect, vec4_t color ) case WP_ABUILD: case WP_ABUILD2: - value = cgs.alienBuildPoints; - break; - case WP_HBUILD: - value = cgs.humanBuildPoints; + value = cg.snap->ps.persistant[ PERS_BP ]; break; default: diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index 8f26df43..5518a329 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -1374,12 +1374,6 @@ typedef struct qboolean newHud; - int alienBuildPoints; - int alienBuildPointsTotal; - int humanBuildPoints; - int humanBuildPointsTotal; - int humanBuildPointsPowered; - int alienStage; int humanStage; int alienCredits; diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c index ae3e179e..2d9b7038 100644 --- a/src/cgame/cg_servercmds.c +++ b/src/cgame/cg_servercmds.c @@ -160,12 +160,6 @@ Called on load to set the initial values from configure strings */ void CG_SetConfigValues( void ) { - sscanf( CG_ConfigString( CS_BUILDPOINTS ), - "%d %d %d %d", &cgs.alienBuildPoints, - &cgs.alienBuildPointsTotal, - &cgs.humanBuildPoints, - &cgs.humanBuildPointsTotal ); - sscanf( CG_ConfigString( CS_STAGES ), "%d %d %d %d %d %d", &cgs.alienStage, &cgs.humanStage, &cgs.alienCredits, &cgs.humanCredits, &cgs.alienNextStageThreshold, &cgs.humanNextStageThreshold ); @@ -279,11 +273,6 @@ static void CG_ConfigStringModified( void ) CG_ParseServerinfo( ); else if( num == CS_WARMUP ) CG_ParseWarmup( ); - else if( num == CS_BUILDPOINTS ) - sscanf( str, "%d %d %d %d", &cgs.alienBuildPoints, - &cgs.alienBuildPointsTotal, - &cgs.humanBuildPoints, - &cgs.humanBuildPointsTotal ); else if( num == CS_STAGES ) { stage_t oldAlienStage = cgs.alienStage; diff --git a/src/game/bg_public.h b/src/game/bg_public.h index 6a4bc1c8..079d55e4 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -69,7 +69,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define CS_BOTINFO 25 #define CS_CLIENTS_READY 26 -#define CS_BUILDPOINTS 28 #define CS_STAGES 29 #define CS_MODELS 33 @@ -269,8 +268,9 @@ typedef enum PERS_STATE, PERS_CREDIT, // human credit PERS_QUEUEPOS, // position in the spawn queue - PERS_NEWWEAPON // weapon to switch to - // netcode has space for 5 more + PERS_NEWWEAPON, // weapon to switch to + PERS_BP + // netcode has space for 4 more } persEnum_t; #define PS_WALLCLIMBINGFOLLOW 0x00000001 diff --git a/src/game/g_active.c b/src/game/g_active.c index e004346a..80c3df65 100644 --- a/src/game/g_active.c +++ b/src/game/g_active.c @@ -1742,6 +1742,12 @@ void ClientThink_real( gentity_t *ent ) } } + client->ps.persistant[ PERS_BP ] = G_GetBuildPoints( client->ps.origin, + client->ps.stats[ STAT_TEAM ], BG_Class( client->ps.stats[ STAT_CLASS ] )->buildDist ); + + if( client->ps.persistant[ PERS_BP ] < 0 ) + client->ps.persistant[ PERS_BP ] = 0; + // Give clients some credit periodically if( ent->client->lastKillTime + FREEKILL_PERIOD < level.time ) { diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index 8d77267a..11ed8db4 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -23,6 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "g_local.h" +zone_t zones[ MAX_ZONES ]; + /* ================ G_SetBuildableAnim @@ -212,7 +214,7 @@ Simple wrapper to G_FindPower to find the entity providing power for the specified point ================ */ -static gentity_t *G_PowerEntityForPoint( vec3_t origin ) +gentity_t *G_PowerEntityForPoint( vec3_t origin ) { gentity_t dummy; @@ -229,90 +231,112 @@ static gentity_t *G_PowerEntityForPoint( vec3_t origin ) /* ================ -G_FindRepeater +G_IsPowered + +Check if a location has power, returning the entity type +that is providing it +================ +*/ +buildable_t G_IsPowered( vec3_t origin ) +{ + gentity_t *ent = G_PowerEntityForPoint( origin ); + + if( ent ) + return ent->s.modelindex; + else + return BA_NONE; +} + +/* +================ +G_RepeaterWouldOverlap -attempt to find a repeater in range of self, return qtrue if successful +Check if a repeater would create an overlapping power zone ================ */ -static qboolean G_FindRepeater( gentity_t *self ) +static qboolean G_RepeaterWouldOverlap( vec3_t origin ) { int i; gentity_t *ent; - gentity_t *closestPower = NULL; - int distance = 0; - int minDistance = REPEATER_BASESIZE + 1; + int distance; vec3_t temp_v; - if( self->buildableTeam != TEAM_HUMANS ) - return qfalse; - - //iterate through entities + // Iterate through entities for( i = MAX_CLIENTS, ent = g_entities + i; i < level.num_entities; i++, ent++ ) { if( ent->s.eType != ET_BUILDABLE ) continue; - //if entity is a power item calculate the distance to it - if( ent->s.modelindex == BA_H_REPEATER && + // If entity is a power item calculate the distance to it + if( ( ent->s.modelindex == BA_H_REACTOR || ent->s.modelindex == BA_H_REPEATER ) && ent->spawned && ent->powered ) { - VectorSubtract( self->s.origin, ent->s.origin, temp_v ); + VectorSubtract( origin, ent->s.origin, temp_v ); distance = VectorLength( temp_v ); - if( distance < minDistance ) + if( ent->s.modelindex == BA_H_REACTOR ) { - closestPower = ent; - minDistance = distance; + if( distance <= REACTOR_BASESIZE + REPEATER_BASESIZE ) + return qtrue; + } + else if( ent->s.modelindex == BA_H_REPEATER ) + { + if( distance <= REPEATER_BASESIZE + REPEATER_BASESIZE ) + return qtrue; } } } - //if there were no power items nearby give up - if( closestPower ) - { - self->parentNode = closestPower; - return qtrue; - } return qfalse; } + /* -================ -G_RepeaterEntityForPoint +================== +G_GetBuildPoints -Simple wrapper to G_FindRepeater to find a repeater providing -power for the specified point -================ +Get the number of build points from a position +================== */ -static gentity_t *G_RepeaterEntityForPoint( vec3_t origin ) +int G_GetBuildPoints( const vec3_t pos, team_t team, int dist ) { - gentity_t dummy; + int i; + gentity_t *ent; + int distance = 0; + vec3_t temp_v; + int buildPoints = 0; - dummy.parentNode = NULL; - dummy.buildableTeam = TEAM_HUMANS; - dummy.s.modelindex = BA_NONE; - VectorCopy( origin, dummy.s.origin ); + if( team == TEAM_HUMANS ) + { + // Iterate through entities + for( i = MAX_CLIENTS, ent = g_entities + i; i < level.num_entities; i++, ent++ ) + { + ent = &g_entities[ i ]; - if( G_FindRepeater( &dummy ) ) - return dummy.parentNode; - else - return NULL; -} -/* -================ -G_IsPowered + VectorSubtract( pos, ent->s.origin, temp_v ); + distance = VectorLength( temp_v ); -Check if a location has power, returning the entity type -that is providing it -================ -*/ -buildable_t G_IsPowered( vec3_t origin ) -{ - gentity_t *ent = G_PowerEntityForPoint( origin ); + if( ent->s.modelindex == BA_H_REACTOR && distance <= REACTOR_BASESIZE + dist ) + { + // Reactor is in range + buildPoints += level.humanBuildPoints; + } + else if( ent->s.modelindex == BA_H_REPEATER && distance <= REPEATER_BASESIZE + dist ) + { + if( ent->usesZone && zones[ent->zone].active ) + { + zone_t *zone = &zones[ent->zone]; - if( ent ) - return ent->s.modelindex; - else - return BA_NONE; + buildPoints += zone->totalBuildPoints - zone->queuedBuildPoints; + } + } + } + } + else if( team == TEAM_ALIENS ) + { + buildPoints = level.alienBuildPoints; + } + + return buildPoints; } /* @@ -1625,6 +1649,48 @@ void ATrapper_Think( gentity_t *self ) +void HSpawn_Blast( gentity_t *ent ); +void HSpawn_Disappear( gentity_t *ent ); + +/* +================ +HRepeater_Die + +Called when a repeater dies +================ +*/ +static void HRepeater_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ) +{ + G_RewardAttackers( self ); + G_SetBuildableAnim( self, BANIM_DESTROY1, qtrue ); + G_SetIdleBuildableAnim( self, BANIM_DESTROYED ); + + self->die = nullDieFunction; + self->powered = qfalse; //free up power + self->s.eFlags &= ~EF_FIRING; //prevent any firing effects + + if( self->spawned ) + { + self->think = HSpawn_Blast; + self->nextthink = level.time + HUMAN_DETONATION_DELAY; + } + else + { + self->think = HSpawn_Disappear; + self->nextthink = level.time; //blast immediately + } + + G_LogDestruction( self, attacker, mod ); + + if( self->usesZone ) + { + zone_t *zone = &zones[self->zone]; + + zone->active = qfalse; + self->usesZone = qfalse; + } +} + /* ================ HRepeater_Think @@ -1637,10 +1703,11 @@ void HRepeater_Think( gentity_t *self ) int i; qboolean reactor = qfalse; gentity_t *ent; + zone_t *zone; if( self->spawned ) { - //iterate through entities + // Iterate through entities for ( i = 1, ent = g_entities + i; i < level.num_entities; i++, ent++ ) { if( ent->s.eType != ET_BUILDABLE ) @@ -1653,7 +1720,7 @@ void HRepeater_Think( gentity_t *self ) if( G_NumberOfDependants( self ) == 0 ) { - //if no dependants for x seconds then disappear + // If no dependants for x seconds then disappear if( self->count < 0 ) self->count = level.time; else if( self->count > 0 && ( ( level.time - self->count ) > REPEATER_INACTIVE_TIME ) ) @@ -1664,6 +1731,29 @@ void HRepeater_Think( gentity_t *self ) self->powered = reactor; + // Initialise the zone once the repeater has spawned + if( self->spawned && ( !self->usesZone || !zones[ self->zone ].active ) ) + { + // See if a free zone exists + for( i = 0; i < MIN( g_humanRepeaterMaxZones.integer, MAX_ZONES ); i++ ) + { + zone = &zones[ i ]; + + if( !zone->active ) + { + // Initialise the BP queue with all BP queued + zone->queuedBuildPoints = zone->totalBuildPoints = g_humanRepeaterBuildPoints.integer; + zone->nextQueueTime = level.time; + zone->active = qtrue; + + self->zone = zone - zones; + self->usesZone = qtrue; + + break; + } + } + } + self->nextthink = level.time + POWER_REFRESH_TIME; } @@ -2398,6 +2488,7 @@ G_QueueBuildPoints void G_QueueBuildPoints( gentity_t *self ) { gentity_t *killer = NULL; + gentity_t *powerEntity; if( self->killedBy != ENTITYNUM_NONE ) killer = &g_entities[ self->killedBy ]; @@ -2425,11 +2516,34 @@ void G_QueueBuildPoints( gentity_t *self ) break; case TEAM_HUMANS: - if( !level.humanBuildPointQueue ) - level.humanNextQueueTime = level.time + g_humanBuildQueueTime.integer; + powerEntity = G_PowerEntityForPoint( self->s.origin ); + + if( powerEntity ) + { + switch( powerEntity->s.modelindex ) + { + default: + case BA_H_REACTOR: + if( !level.humanBuildPointQueue ) + level.humanNextQueueTime = level.time + g_humanBuildQueueTime.integer; + + level.humanBuildPointQueue += + BG_Buildable( self->s.modelindex )->buildPoints; + break; + + case BA_H_REPEATER: + if( powerEntity->usesZone && zones[powerEntity->zone].active ) + { + zone_t *zone = &zones[powerEntity->zone]; - level.humanBuildPointQueue += - BG_Buildable( self->s.modelindex )->buildPoints; + if( !zone->queuedBuildPoints ) + zone->nextQueueTime = level.time + g_humanRepeaterBuildQueueTime.integer; + zone->queuedBuildPoints += + BG_Buildable( self->s.modelindex )->buildPoints; + } + break; + } + } break; } } @@ -2813,7 +2927,7 @@ static itemBuildError_t G_SufficientBPAvailable( buildable_t buildable, if( team == TEAM_ALIENS ) { - remainingBP = level.alienBuildPoints; + remainingBP = G_GetBuildPoints( origin, team, 0 ); remainingSpawns = level.numAlienSpawns; bpError = IBE_NOALIENBP; spawn = BA_A_SPAWN; @@ -2821,7 +2935,7 @@ static itemBuildError_t G_SufficientBPAvailable( buildable_t buildable, } else if( team == TEAM_HUMANS ) { - remainingBP = level.humanBuildPoints; + remainingBP = G_GetBuildPoints( origin, team, 0 ); remainingSpawns = level.numHumanSpawns; bpError = IBE_NOHUMANBP; spawn = BA_H_SPAWN; @@ -2889,6 +3003,13 @@ static itemBuildError_t G_SufficientBPAvailable( buildable_t buildable, else repeaterInRange = qfalse; + // Don't allow marked buildables to be replaced in another zone, + // unless the marked buildable is unpowered + if( buildable != BA_H_REACTOR && buildable != BA_H_REPEATER && + G_PowerEntityForPoint( ent->s.origin ) != G_PowerEntityForPoint( origin ) && + G_PowerEntityForPoint( ent->s.origin ) ) + continue; + if( !ent->inuse ) continue; @@ -2907,6 +3028,11 @@ static itemBuildError_t G_SufficientBPAvailable( buildable_t buildable, if( ent->s.modelindex == core && buildable != core ) continue; + // Don't allow a power source to be replaced by a non-power source + if( buildable != BA_H_REACTOR && buildable != BA_H_REPEATER && + ( ent->s.modelindex == BA_H_REACTOR || ent->s.modelindex == BA_H_REPEATER ) ) + continue; + if( ent->deconstruct ) { level.markedBuildables[ numBuildables++ ] = ent; @@ -3066,6 +3192,9 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance contents = trap_PointContents( entity_origin, -1 ); buildPoints = BG_Buildable( buildable )->buildPoints; + if( ( tempReason = G_SufficientBPAvailable( buildable, origin ) ) != IBE_NONE ) + reason = tempReason; + if( ent->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS ) { //alien criteria @@ -3122,8 +3251,11 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance if( tempent == NULL ) // No reactor reason = IBE_RPTNOREAC; - else if( !g_markDeconstruct.integer && G_RepeaterEntityForPoint( entity_origin ) ) + else if( G_RepeaterWouldOverlap( entity_origin ) ) + { + // The repeater would cause power zones to overlap reason = IBE_RPTPOWERHERE; + } } // Check permission to build here @@ -3162,9 +3294,6 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance } } - if( ( tempReason = G_SufficientBPAvailable( buildable, origin ) ) != IBE_NONE ) - reason = tempReason; - // Relink buildables G_SetBuildableLinkState( qtrue ); @@ -3355,7 +3484,7 @@ static gentity_t *G_Build( gentity_t *builder, buildable_t buildable, vec3_t ori case BA_H_REPEATER: built->think = HRepeater_Think; - built->die = HSpawn_Die; + built->die = HRepeater_Die; built->use = HRepeater_Use; built->count = -1; break; diff --git a/src/game/g_local.h b/src/game/g_local.h index 933028cd..e757653d 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -252,6 +252,9 @@ struct gentity_s qboolean ownerClear; // used for missle tracking qboolean pointAgainstWorld; // don't use the bbox for map collisions + + int zone; // index for zone + int usesZone; // does it use a zone? }; typedef enum @@ -698,6 +701,8 @@ void G_Physics( gentity_t *ent, int msec ); #define MAX_ALIEN_BBOX 25 +#define MAX_ZONES 1024 + typedef enum { IBE_NONE, @@ -726,6 +731,17 @@ typedef enum IBE_MAXERRORS } itemBuildError_t; +typedef struct +{ + int active; + + int totalBuildPoints; + int queuedBuildPoints; + int nextQueueTime; +} zone_t; + +extern zone_t zones[MAX_ZONES]; + qboolean AHovel_Blocked( gentity_t *hovel, gentity_t *player, qboolean provideExit ); gentity_t *G_CheckSpawnPoint( int spawnNum, vec3_t origin, vec3_t normal, buildable_t spawn, vec3_t spawnOrigin ); @@ -750,6 +766,8 @@ void G_LayoutSelect( void ); void G_LayoutLoad( void ); void G_BaseSelfDestruct( team_t team ); void G_QueueBuildPoints( gentity_t *self ); +int G_GetBuildPoints( const vec3_t pos, team_t team, int dist ); +gentity_t *G_PowerEntityForPoint( vec3_t origin ); // // g_utils.c @@ -1059,10 +1077,13 @@ extern vmCvar_t g_enableDust; extern vmCvar_t g_enableBreath; extern vmCvar_t g_singlePlayer; -extern vmCvar_t g_humanBuildPoints; extern vmCvar_t g_alienBuildPoints; -extern vmCvar_t g_humanBuildQueueTime; extern vmCvar_t g_alienBuildQueueTime; +extern vmCvar_t g_humanBuildPoints; +extern vmCvar_t g_humanBuildQueueTime; +extern vmCvar_t g_humanRepeaterBuildPoints; +extern vmCvar_t g_humanRepeaterBuildQueueTime; +extern vmCvar_t g_humanRepeaterMaxZones; extern vmCvar_t g_humanStage; extern vmCvar_t g_humanCredits; extern vmCvar_t g_humanMaxStage; diff --git a/src/game/g_main.c b/src/game/g_main.c index cca612bc..02448be4 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -87,10 +87,13 @@ vmCvar_t g_minCommandPeriod; vmCvar_t g_minNameChangePeriod; vmCvar_t g_maxNameChanges; -vmCvar_t g_humanBuildPoints; vmCvar_t g_alienBuildPoints; -vmCvar_t g_humanBuildQueueTime; vmCvar_t g_alienBuildQueueTime; +vmCvar_t g_humanBuildPoints; +vmCvar_t g_humanBuildQueueTime; +vmCvar_t g_humanRepeaterBuildPoints; +vmCvar_t g_humanRepeaterBuildQueueTime; +vmCvar_t g_humanRepeaterMaxZones; vmCvar_t g_humanStage; vmCvar_t g_humanCredits; vmCvar_t g_humanMaxStage; @@ -222,10 +225,13 @@ static cvarTable_t gameCvarTable[ ] = { &pmove_fixed, "pmove_fixed", "0", CVAR_SYSTEMINFO, 0, qfalse}, { &pmove_msec, "pmove_msec", "8", CVAR_SYSTEMINFO, 0, qfalse}, - { &g_humanBuildPoints, "g_humanBuildPoints", DEFAULT_HUMAN_BUILDPOINTS, 0, 0, qfalse }, { &g_alienBuildPoints, "g_alienBuildPoints", DEFAULT_ALIEN_BUILDPOINTS, 0, 0, qfalse }, - { &g_humanBuildQueueTime, "g_humanBuildQueueTime", DEFAULT_HUMAN_QUEUE_TIME, 0, 0, qfalse }, { &g_alienBuildQueueTime, "g_alienBuildQueueTime", DEFAULT_ALIEN_QUEUE_TIME, 0, 0, qfalse }, + { &g_humanBuildPoints, "g_humanBuildPoints", DEFAULT_HUMAN_BUILDPOINTS, 0, 0, qfalse }, + { &g_humanBuildQueueTime, "g_humanBuildQueueTime", DEFAULT_HUMAN_QUEUE_TIME, 0, 0, qfalse }, + { &g_humanRepeaterBuildPoints, "g_humanRepeaterBuildPoints", DEFAULT_HUMAN_REPEATER_BUILDPOINTS, 0, 0, qfalse }, + { &g_humanRepeaterMaxZones, "g_humanRepeaterMaxZones", DEFAULT_HUMAN_REPEATER_MAX_ZONES, 0, 0, qfalse }, + { &g_humanRepeaterBuildQueueTime, "g_humanRepeaterBuildQueueTime", DEFAULT_HUMAN_REPEATER_QUEUE_TIME, 0, 0, qfalse }, { &g_humanStage, "g_humanStage", "0", 0, 0, qfalse }, { &g_humanCredits, "g_humanCredits", "0", 0, 0, qfalse }, { &g_humanMaxStage, "g_humanMaxStage", DEFAULT_HUMAN_MAX_STAGE, 0, 0, qfalse }, @@ -1063,11 +1069,10 @@ Recalculate the quantity of building points available to the teams */ void G_CalculateBuildPoints( void ) { - int i; + int i, j; buildable_t buildable; gentity_t *ent; - int localHTP = level.humanBuildPoints = g_humanBuildPoints.integer, - localATP = level.alienBuildPoints = g_alienBuildPoints.integer; + zone_t *zone; // BP queue updates while( level.alienBuildPointQueue > 0 && @@ -1112,9 +1117,6 @@ void G_CalculateBuildPoints( void ) ( g_suddenDeath.integer || G_TimeTilSuddenDeath( ) <= 0 ) ) { // begin sudden death - localHTP = 0; - localATP = 0; - if( level.suddenDeathWarning < TW_PASSED ) { G_LogPrintf( "Beginning Sudden Death\n" ); @@ -1140,8 +1142,8 @@ void G_CalculateBuildPoints( void ) } } - level.humanBuildPoints = localHTP - level.humanBuildPointQueue; - level.alienBuildPoints = localATP - level.alienBuildPointQueue; + level.humanBuildPoints = g_humanBuildPoints.integer; + level.alienBuildPoints = g_alienBuildPoints.integer; level.reactorPresent = qfalse; level.overmindPresent = qfalse; @@ -1149,7 +1151,56 @@ void G_CalculateBuildPoints( void ) level.numAlienSpawns = 0; level.numHumanSpawns = 0; - for( i = MAX_CLIENTS, ent = g_entities + i ; i < level.num_entities ; i++, ent++ ) + // Deactivate any unowned zones + for( i = 0; i < MIN( g_humanRepeaterMaxZones.integer, MAX_ZONES ); i++ ) + { + qboolean inUse = qfalse; + zone_t *zone = &zones[ i ]; + + if( zone->active ) + { + for( j = MAX_CLIENTS, ent = g_entities + j ; j < level.num_entities ; j++, ent++ ) + { + if( ent->s.eType != ET_BUILDABLE ) + continue; + + if( ent->s.eType != ET_BUILDABLE ) + continue; + + if( ent->s.eFlags & EF_DEAD ) + continue; + + if( ent->usesZone && ent->zone == i ) + inUse = qtrue; + } + + if( !inUse ) + zone->active = qfalse; + } + } + + // First reset repeater zone BP + for( i = 1, ent = g_entities + i ; i < level.num_entities ; i++, ent++ ) + { + if( ent->s.eType != ET_BUILDABLE ) + continue; + + if( ent->s.eFlags & EF_DEAD ) + continue; + + if( ent->s.modelindex != BA_H_REPEATER ) + continue; + + if( ent->usesZone && zones[ ent->zone ].active ) + { + zone_t *zone = &zones[ ent->zone ]; + + zone->totalBuildPoints = g_humanRepeaterBuildPoints.integer; + } + } + + // Iterate through entities + for( i = 1, ent = g_entities + i ; i < level.num_entities ; i++, ent++ ) { if( !ent->inuse ) continue; @@ -1178,7 +1229,58 @@ void G_CalculateBuildPoints( void ) if( BG_Buildable( buildable )->team == TEAM_HUMANS ) { - level.humanBuildPoints -= BG_Buildable( buildable )->buildPoints; + gentity_t *powerEntity = G_PowerEntityForPoint( ent->s.origin ); + + if( powerEntity ) + { + switch( powerEntity->s.modelindex ) + { + case BA_H_REACTOR: + level.humanBuildPoints -= BG_Buildable( buildable )->buildPoints; + break; + + case BA_H_REPEATER: + if( powerEntity->usesZone && zones[powerEntity->zone].active ) + { + zone_t *zone = &zones[powerEntity->zone]; + + zone->totalBuildPoints -= BG_Buildable( buildable )->buildPoints; + powerEntity->s.misc = zone->totalBuildPoints - zone->queuedBuildPoints; + } + break; + + default: + break; + } + } + else + { + // Unpowered buildables count as BP for the main reactor zone + level.humanBuildPoints -= BG_Buildable( buildable )->buildPoints; + } + + if( buildable == BA_H_REPEATER ) + { + if( ent->usesZone && zones[ ent->zone ].active ) + { + zone = &zones[ ent->zone ]; + + if( !level.suddenDeath ) + { + // BP queue updates + while( zone->queuedBuildPoints > 0 && + zone->nextQueueTime < level.time ) + { + zone->queuedBuildPoints--; + zone->nextQueueTime += (int)g_humanRepeaterBuildQueueTime.integer * (float)( 1 - ( (float)zone->queuedBuildPoints ) / zone->totalBuildPoints ); + } + } + else + { + zone->totalBuildPoints = zone->queuedBuildPoints = 0; + } + } + } } else if( BG_Buildable( buildable )->team == TEAM_ALIENS ) { @@ -1188,20 +1290,10 @@ void G_CalculateBuildPoints( void ) } if( level.humanBuildPoints < 0 ) - { - localHTP -= level.humanBuildPoints; level.humanBuildPoints = 0; - } if( level.alienBuildPoints < 0 ) - { - localATP -= level.alienBuildPoints; level.alienBuildPoints = 0; - } - - trap_SetConfigstring( CS_BUILDPOINTS, va( "%d %d %d %d", - level.alienBuildPoints, localATP, - level.humanBuildPoints, localHTP ) ); } /* diff --git a/src/game/tremulous.h b/src/game/tremulous.h index 7859173e..b71db8ae 100644 --- a/src/game/tremulous.h +++ b/src/game/tremulous.h @@ -660,12 +660,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define FREEKILL_HUMAN LEVEL0_VALUE #define DEFAULT_ALIEN_BUILDPOINTS "100" -#define DEFAULT_ALIEN_QUEUE_TIME "1250" +#define DEFAULT_ALIEN_QUEUE_TIME "7000" #define DEFAULT_ALIEN_STAGE2_THRESH "8000" #define DEFAULT_ALIEN_STAGE3_THRESH "16000" #define DEFAULT_ALIEN_MAX_STAGE "2" #define DEFAULT_HUMAN_BUILDPOINTS "100" -#define DEFAULT_HUMAN_QUEUE_TIME "1250" +#define DEFAULT_HUMAN_QUEUE_TIME "7000" +#define DEFAULT_HUMAN_REPEATER_BUILDPOINTS "20" +#define DEFAULT_HUMAN_REPEATER_QUEUE_TIME "7000" +#define DEFAULT_HUMAN_REPEATER_MAX_ZONES "3" #define DEFAULT_HUMAN_STAGE2_THRESH "4000" #define DEFAULT_HUMAN_STAGE3_THRESH "8000" #define DEFAULT_HUMAN_MAX_STAGE "2" |