diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c index 87d444c..dc0c70b 100644 --- a/src/cgame/cg_draw.c +++ b/src/cgame/cg_draw.c @@ -2245,10 +2245,14 @@ CG_DrawLocation static void CG_DrawLocation( rectDef_t *rect, float scale, int textalign, vec4_t color ) { const char *location; + centity_t *locent; float maxX; float tx = rect->x, ty = rect->y; maxX = rect->x + rect->w; - location = CG_ConfigString(CS_LOCATIONS + cgs.clientinfo[ cg.clientNum ].location); + if( !cg.locationLinked ) + CG_LocationLinkup(); + locent = CG_GetLocation( &cg_entities[ cg.clientNum ] ); + location = CG_ConfigString( CS_LOCATIONS + locent->currentState.misc ); if( UI_Text_Width( location, scale, 0 ) < rect->w ) CG_AlignText( rect, location, scale, 0.0f, 0.0f, textalign, VALIGN_CENTER, &tx, &ty ); diff --git a/src/cgame/cg_ents.c b/src/cgame/cg_ents.c index 7723e48..0e33b62 100644 --- a/src/cgame/cg_ents.c +++ b/src/cgame/cg_ents.c @@ -1212,3 +1212,29 @@ void CG_AddPacketEntities( void ) } } +void CG_LocationLinkup( void ) +{ + int i; + int n; + centity_t *ent; + + + if( cg.time - cgs.levelStartTime < 1000 ) + return; + if( cg.locationLinked ) + return; + + cg.locationLinked = qtrue; + + cg.locationHead = NULL; + + for( i = 0, ent = cg_entities, n = 1; i < MAX_GENTITIES; i++, ent++) + { + if( ent->valid && ent->currentState.eType == ET_LOCATION ) + { + ent->nextTrain = cg.locationHead; + cg.locationHead = ent; + CG_Printf("linking location: %i %i %i\n", i, n, ent->currentState.misc); + } + } +} diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index a1fbb34..7c97f64 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -680,6 +680,7 @@ typedef struct centity_s qboolean valid; qboolean oldValid; + struct centity_s *nextTrain; } centity_t; @@ -1159,6 +1160,9 @@ typedef struct float healthCrossFade; int nextWeaponClickTime; + + centity_t *locationHead; + qboolean locationLinked; } cg_t; @@ -1646,6 +1650,7 @@ void CG_PrecacheClientInfo( class_t class, char *model, char *skin ); sfxHandle_t CG_CustomSound( int clientNum, const char *soundName ); void CG_PlayerDisconnect( vec3_t org ); void CG_Bleed( vec3_t origin, vec3_t normal, int entityNum ); +centity_t *CG_GetLocation( centity_t *cent ); // // cg_buildable.c @@ -1709,7 +1714,7 @@ void CG_PositionEntityOnTag( refEntity_t *entity, const refEntity_t *pare qhandle_t parentModel, char *tagName ); void CG_PositionRotatedEntityOnTag( refEntity_t *entity, const refEntity_t *parent, qhandle_t parentModel, char *tagName ); - +void CG_LocationLinkup( void ); diff --git a/src/cgame/cg_players.c b/src/cgame/cg_players.c index 4fe7e47..2a0621d 100644 --- a/src/cgame/cg_players.c +++ b/src/cgame/cg_players.c @@ -2447,3 +2447,35 @@ void CG_PlayerDisconnect( vec3_t org ) } } +centity_t *CG_GetLocation( centity_t *cent ) +{ + centity_t *eloc, *best; + float bestlen, len; + vec3_t origin; + trace_t tr; + + best = NULL; + bestlen = 3.0f * 8192.0f * 8192.0f; + + VectorCopy( cent->lerpOrigin, origin ); + + for( eloc = cg.locationHead; eloc; eloc = eloc->nextTrain ) + { + len = DistanceSquared(origin, eloc->lerpOrigin); + /*( origin[ 0 ] - eloc->r.currcentOrigin[ 0 ] ) * ( origin[ 0 ] - eloc->r.currcentOrigin[ 0 ] ) + + ( origin[ 1 ] - eloc->r.currcentOrigin[ 1 ] ) * ( origin[ 1 ] - eloc->r.currcentOrigin[ 1 ] ) + + ( origin[ 2 ] - eloc->r.currcentOrigin[ 2 ] ) * ( origin[ 2 ] - eloc->r.currcentOrigin[ 2 ] ); + */ + if( len > bestlen ) + continue; + + CG_Trace( &tr, origin, NULL, NULL, eloc->lerpOrigin, 0, CONTENTS_SOLID ); + if( tr.fraction < 1.0f ) + continue; + + bestlen = len; + best = eloc; + } + + return best; +} diff --git a/src/game/bg_public.h b/src/game/bg_public.h index 090aff8..1149d95 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -1162,6 +1162,8 @@ typedef enum ET_BUILDABLE, // buildable type + ET_LOCATION, + ET_MISSILE, ET_MOVER, ET_BEAM, diff --git a/src/game/g_target.c b/src/game/g_target.c index b2c2d9a..5c38f60 100644 --- a/src/game/g_target.c +++ b/src/game/g_target.c @@ -298,10 +298,10 @@ static void target_location_linkup( gentity_t *ent ) for( i = 0, ent = g_entities, n = 1; i < level.num_entities; i++, ent++) { - if( ent->classname && !Q_stricmp( ent->classname, "target_location" ) ) + if( ent->s.eType == ET_LOCATION ) { // lets overload some variables! - ent->health = n; // use for location marking + ent->s.misc = n; // use for location marking trap_SetConfigstring( CS_LOCATIONS + n, ent->message ); n++; ent->nextTrain = level.locationHead; @@ -323,7 +323,7 @@ void SP_target_location( gentity_t *self ) { self->think = target_location_linkup; self->nextthink = level.time + 200; // Let them all spawn first - + self->s.eType = ET_LOCATION; G_SetOrigin( self, self->s.origin ); } diff --git a/src/game/g_team.c b/src/game/g_team.c index 76b2719..b0088ff 100644 --- a/src/game/g_team.c +++ b/src/game/g_team.c @@ -77,7 +77,7 @@ gentity_t *Team_GetLocation( gentity_t *ent ) best = NULL; bestlen = 3.0f * 8192.0f * 8192.0f; - VectorCopy( ent->client->ps.origin, origin ); + VectorCopy( ent->r.currentOrigin, origin ); for( eloc = level.locationHead; eloc; eloc = eloc->nextTrain ) { @@ -160,26 +160,9 @@ void TeamplayInfoMessage( gentity_t *ent ) int h, a = 0; int clients[ TEAM_MAXOVERLAY ]; - //hack: always send each client's teaminfo to it for CG_PLAYER_LOCATION - h = ent->client->ps.stats[ STAT_HEALTH ]; - if( h < 0 ) - h = 0; - trap_SendServerCommand( ent - g_entities, - va("tinfo %i %i %i %i %i %i", - 1, - ent - g_entities, - ent->client->pers.location, - h, - a, - ent->client->ps.weapon ) ); if( ! ent->client->pers.teamInfo ) return; - if( !ent->inuse || - ( !( ent->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS ) && - !( ent->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS ) ) ) - return; - // figure out what client should be on the display // we are limited to 8, but we want to use the top eight players // but in client order (so they don't keep changing position on the overlay) @@ -244,12 +227,18 @@ void CheckTeamStatus( void ) ent = g_entities + i; if( ent->client->pers.connected != CON_CONNECTED ) continue; - loc = Team_GetLocation( ent ); - if( loc ) - ent->client->pers.location = loc->health; - else - ent->client->pers.location = 0; - + + if( ent->inuse && ( ent->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS || + ent->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS ) ) + { + + loc = Team_GetLocation( ent ); + + if( loc ) + ent->client->pers.location = loc->health; + else + ent->client->pers.location = 0; + } } for( i = 0; i < g_maxclients.integer; i++ ) @@ -258,7 +247,9 @@ void CheckTeamStatus( void ) if( ent->client->pers.connected != CON_CONNECTED ) continue; - TeamplayInfoMessage( ent ); + if( ent->inuse && ( ent->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS || + ent->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS ) ) + TeamplayInfoMessage( ent ); } } }