summaryrefslogtreecommitdiff
path: root/src/game/g_buildable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/g_buildable.c')
-rw-r--r--src/game/g_buildable.c101
1 files changed, 83 insertions, 18 deletions
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index 6a0fde75..f479d353 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -2607,11 +2607,12 @@ static qboolean G_SufficientBPAvailable( buildableTeam_t team,
buildable_t buildable )
{
int i;
- int numBuildables = 0;
+ int numBuildables = level.numBuildablesForRemoval;
int pointsYielded = 0;
gentity_t *ent;
qboolean unique = BG_FindUniqueTestForBuildable( buildable );
int remainingBP, remainingSpawns;
+ int numBuildablesInTheWay = level.numBuildablesForRemoval;
if( team == BIT_ALIENS )
{
@@ -2675,23 +2676,29 @@ static qboolean G_SufficientBPAvailable( buildableTeam_t team,
if( buildPoints > 0 && numBuildables == 0 )
return qfalse;
- // Sort the list
- qsort( level.markedBuildables, numBuildables, sizeof( level.markedBuildables[ 0 ] ),
- G_CompareBuildablesForRemoval );
+ // Sort everything that was added to the list, but leave what was already
+ // there in the front (those buildings are blocking the new buildable)
+ qsort( level.markedBuildables + numBuildablesInTheWay,
+ numBuildables - numBuildablesInTheWay,
+ sizeof( level.markedBuildables[ 0 ] ), G_CompareBuildablesForRemoval );
- // Do a pass looking for a buildable of the same type that we're
- // building and mark it (and only it) for destruction if found
- for( i = 0; i < numBuildables; i++ )
+ // if any buildings are in the way of what we're building
+ // we must force them to be deconned regardless of bp, so this won't work
+ if( numBuildablesInTheWay == 0 )
{
- ent = level.markedBuildables[ i ];
-
- if( ent->s.modelindex == buildable )
+ // Do a pass looking for a buildable of the same type that we're
+ // building and mark it (and only it) for destruction if found
+ for( i = 0; i < numBuildables; i++ )
{
- // If we're removing what we're building this will always work
- level.markedBuildables[ 0 ] = ent;
- level.numBuildablesForRemoval = 1;
+ ent = level.markedBuildables[ i ];
- return qtrue;
+ if( ent->s.modelindex == buildable )
+ {
+ // If we're removing what we're building this will always work
+ level.markedBuildables[ 0 ] = ent;
+ level.numBuildablesForRemoval = 1;
+ return qtrue;
+ }
}
}
@@ -2703,6 +2710,11 @@ static qboolean G_SufficientBPAvailable( buildableTeam_t team,
pointsYielded += BG_FindBuildPointsForBuildable( ent->s.modelindex );
}
+ if( level.numBuildablesForRemoval < numBuildablesInTheWay )
+ {
+ level.numBuildablesForRemoval = numBuildablesInTheWay;
+ }
+
// Not enough points yielded
if( pointsYielded < buildPoints )
{
@@ -2726,7 +2738,9 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance
{
vec3_t angles;
vec3_t entity_origin, normal;
- vec3_t mins, maxs;
+ vec3_t mins, maxs, mins1, maxs1;
+ int num;
+ int entitylist[ MAX_GENTITIES ];
trace_t tr1, tr2, tr3;
int i;
itemBuildError_t reason = IBE_NONE;
@@ -2740,9 +2754,11 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance
BG_FindBBoxForBuildable( buildable, mins, maxs );
BG_PositionBuildableRelativeToPlayer( ps, mins, maxs, trap_Trace, entity_origin, angles, &tr1 );
-
- trap_Trace( &tr2, entity_origin, mins, maxs, entity_origin, ent->s.number, MASK_PLAYERSOLID );
- trap_Trace( &tr3, ps->origin, NULL, NULL, entity_origin, ent->s.number, MASK_PLAYERSOLID );
+ VectorAdd( entity_origin, mins, mins1 );
+ VectorAdd( entity_origin, maxs, maxs1 );
+ num = trap_EntitiesInBox( mins1, maxs1, entitylist, MAX_GENTITIES );
+ trap_Trace( &tr2, entity_origin, mins, maxs, entity_origin, ent->s.number, MASK_DEADSOLID );
+ trap_Trace( &tr3, ps->origin, NULL, NULL, entity_origin, ent->s.number, MASK_DEADSOLID );
VectorCopy( entity_origin, origin );
@@ -2764,6 +2780,55 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance
contents = trap_PointContents( entity_origin, -1 );
buildPoints = BG_FindBuildPointsForBuildable( buildable );
+ //force buildings that are blocking the current building to be
+ //deconstructed before other marked buildings
+ level.numBuildablesForRemoval = 0;
+ for(i = 0; i < num; i++)
+ {
+ gentity_t *tent = &g_entities[ entitylist[ i ] ];
+ if( tent->s.eType == ET_PLAYER )
+ {
+ reason = IBE_NOROOM;
+ break;
+ }
+ else if( tent->biteam != ent->client->ps.stats[ STAT_PTEAM ] )
+ {
+ reason = IBE_NOROOM;
+ }
+ else if( tent->s.eType == ET_BUILDABLE && !tent->deconstruct )
+ {
+ reason = IBE_NOROOM;
+ break;
+ }
+ else
+ {
+ if( tent->s.modelindex == BA_H_SPAWN && level.numHumanSpawns <= 1 )
+ {
+ reason = IBE_NOROOM;
+ break;
+ }
+ else if( tent->s.modelindex == BA_A_SPAWN && level.numHumanSpawns <= 1 )
+ {
+ reason = IBE_NOROOM;
+ break;
+ }
+ else if( tent->s.modelindex == BA_H_REACTOR && buildable != BA_H_REACTOR )
+ {
+ reason = IBE_NOROOM;
+ break;
+ }
+ else if( tent->s.modelindex == BA_A_OVERMIND && buildable != BA_A_OVERMIND )
+ {
+ reason = IBE_NOROOM;
+ break;
+ }
+ level.markedBuildables[ level.numBuildablesForRemoval++ ] = tent;
+ }
+ }
+ if( reason != IBE_NONE )
+ {
+ level.numBuildablesForRemoval = 0;
+ }
if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
{
//alien criteria