diff options
Diffstat (limited to 'src/game/g_buildable.c')
| -rw-r--r-- | src/game/g_buildable.c | 144 | 
1 files changed, 144 insertions, 0 deletions
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index 3b237379..34136909 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -789,6 +789,7 @@ void AGeneric_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, i    else      self->nextthink = level.time; //blast immediately +  G_RemoveRangeMarkerFrom( self );    G_LogDestruction( self, attacker, mod );  } @@ -1661,6 +1662,7 @@ void HSpawn_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int      self->nextthink = level.time; //blast immediately    } +  G_RemoveRangeMarkerFrom( self );    G_LogDestruction( self, attacker, mod );  } @@ -1747,6 +1749,7 @@ static void HRepeater_Die( gentity_t *self, gentity_t *inflictor, gentity_t *att      self->nextthink = level.time; //blast immediately    } +  G_RemoveRangeMarkerFrom( self );    G_LogDestruction( self, attacker, mod );    if( self->usesBuildPointZone ) @@ -3020,6 +3023,7 @@ void G_FreeMarkedBuildables( gentity_t *deconner, char *readable, int rsize,      if( nums )        Q_strcat( nums, nsize, va( " %d", (int)( ent - g_entities ) ) ); +    G_RemoveRangeMarkerFrom( ent );      G_FreeEntity( ent );    } @@ -3491,6 +3495,55 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance  /*  ================ +G_AddRangeMarkerForBuildable +================ +*/ +static void G_AddRangeMarkerForBuildable( gentity_t *self ) +{ +  gentity_t *rm; + +  switch( self->s.modelindex ) +  { +    case BA_A_SPAWN: +    case BA_A_OVERMIND: +    case BA_A_ACIDTUBE: +    case BA_A_TRAPPER: +    case BA_A_HIVE: +    case BA_H_MGTURRET: +    case BA_H_TESLAGEN: +    case BA_H_DCC: +    case BA_H_REACTOR: +    case BA_H_REPEATER: +      break; +    default: +      return; +  } + +  rm = G_Spawn(); +  rm->classname = "buildablerangemarker"; +  rm->r.svFlags = SVF_BROADCAST | SVF_CLIENTMASK; +  rm->s.eType = ET_RANGE_MARKER; +  rm->s.modelindex = self->s.modelindex; + +  self->rangeMarker = rm; +} + +/* +================ +G_RemoveRangeMarkerFrom +================ +*/ +void G_RemoveRangeMarkerFrom( gentity_t *self ) +{ +  if( self->rangeMarker ) +  { +    G_FreeEntity( self->rangeMarker ); +    self->rangeMarker = NULL; +  } +} + +/* +================  G_Build  Spawns a buildable @@ -3719,6 +3772,8 @@ static gentity_t *G_Build( gentity_t *builder, buildable_t buildable,    if( log )      G_BuildLogSet( log, built ); +  G_AddRangeMarkerForBuildable( built ); +    return built;  } @@ -3840,6 +3895,7 @@ static gentity_t *G_FinishSpawningBuildable( gentity_t *ent, qboolean force )    {      G_Printf( S_COLOR_YELLOW "G_FinishSpawningBuildable: %s startsolid at %s\n",                built->classname, vtos( built->s.origin ) ); +    G_RemoveRangeMarkerFrom( built );      G_FreeEntity( built );      return NULL;    } @@ -4309,6 +4365,7 @@ void G_BuildLogRevert( int id )              if( ent->s.eType == ET_BUILDABLE )                G_LogPrintf( "revert: remove %d %s\n",                  (int)( ent - g_entities ), BG_Buildable( ent->s.modelindex )->name ); +            G_RemoveRangeMarkerFrom( ent );              G_FreeEntity( ent );              break;            } @@ -4370,3 +4427,90 @@ void G_BuildLogRevert( int id )    }  } +/* +================ +G_UpdateBuildableRangeMarkers +================ +*/ +void G_UpdateBuildableRangeMarkers( void ) +{ +  // is the entity 64-bit client-masking extension available? +  qboolean maskingExtension = ( trap_Cvar_VariableIntegerValue( "sv_gppExtension" ) >= 1 ); + +  gentity_t *e; +  for( e = &g_entities[ MAX_CLIENTS ]; e < &g_entities[ level.num_entities ]; ++e ) +  { +    buildable_t bType; +    team_t bTeam; +    int i; + +    if( e->s.eType != ET_BUILDABLE || !e->rangeMarker ) +      continue; + +    bType = e->s.modelindex; +    bTeam = BG_Buildable( bType )->team; + +    e->rangeMarker->s.pos = e->s.pos; +    if( bType == BA_A_HIVE || bType == BA_H_TESLAGEN ) +      VectorMA( e->s.pos.trBase, e->r.maxs[ 2 ], e->s.origin2, e->rangeMarker->s.pos.trBase ); +    else if( bType == BA_A_TRAPPER || bType == BA_H_MGTURRET ) +      vectoangles( e->s.origin2, e->rangeMarker->s.apos.trBase ); + +    e->rangeMarker->r.singleClient = 0; +    e->rangeMarker->r.hack.generic1 = 0; + +    // remove any previously added NOCLIENT flags from the hack below +    e->rangeMarker->r.svFlags &= ~SVF_NOCLIENT; + +    for( i = 0; i < level.maxclients; ++i ) +    { +      gclient_t *client; +      team_t team; +      qboolean weaponDisplays, wantsToSee; + +      client = &level.clients[ i ]; +      if( client->pers.connected != CON_CONNECTED ) +        continue; + +      if( i >= 32 && !maskingExtension ) +      { +        // resort to not sending range markers at all +        if( !trap_Cvar_VariableIntegerValue( "g_rangeMarkerWarningGiven" ) ) +        { +          trap_SendServerCommand( -1, "print \"" S_COLOR_YELLOW "WARNING: There is no " +            "support for entity 64-bit client-masking on this server. Please update " +            "your server executable. Until then, range markers will not be displayed " +            "while there are clients with client numbers above 31 in the game.\n\"" ); +          trap_Cvar_Set( "g_rangeMarkerWarningGiven", "1" ); +        } + +        for( e = &g_entities[ MAX_CLIENTS ]; e < &g_entities[ level.num_entities ]; ++e ) +        { +          if( e->s.eType == ET_BUILDABLE && e->rangeMarker ) +            e->rangeMarker->r.svFlags |= SVF_NOCLIENT; +        } + +        return; +      } + +      team = client->pers.teamSelection; +      if( team != TEAM_NONE ) +      { +        weaponDisplays = ( BG_InventoryContainsWeapon( WP_HBUILD, client->ps.stats ) || +          client->ps.weapon == WP_ABUILD || client->ps.weapon == WP_ABUILD2 ); +      } +      wantsToSee = !!( client->pers.buildableRangeMarkerMask & ( 1 << bType ) ); + +      if( ( team == TEAM_NONE || ( team == bTeam && weaponDisplays ) ) && wantsToSee ) +      { +        if( i >= 32 ) +          e->rangeMarker->r.hack.generic1 |= 1 << ( i - 32 ); +        else +          e->rangeMarker->r.singleClient |= 1 << i; +      } +    } + +    trap_LinkEntity( e->rangeMarker ); +  } +} +  | 
