static void Say_Team_Drop_Location( edict_t *who, char *buf, int buflen, const char *current_color ) { if( !who->r.client->teamstate.last_drop_item ) { buf[0] = 0; } else { G_MapLocationNameForTAG( G_MapLocationTAGForOrigin( who->r.client->teamstate.last_drop_location ), buf, buflen ); Q_strncatz( buf, current_color, buflen ); } }
/* * Spawn_ItemTimer */ static edict_t *Spawn_ItemTimer( edict_t *ent ) { edict_t *timer; int locationTag; // location tag locationTag = G_MapLocationTAGForOrigin( ent->s.origin ); // item timer is a special entity type, carrying information about its parent item entity // which is only visible to spectators timer = G_Spawn(); timer->s.type = ET_ITEM_TIMER; timer->s.itemNum = ent->s.itemNum; timer->s.team = TEAM_SPECTATOR; timer->r.svflags = SVF_ONLYTEAM | SVF_BROADCAST; timer->r.owner = ent; timer->s.modelindex = 0; timer->s.modelindex2 = locationTag; timer->nextThink = level.time + 250; timer->think = item_timer_think; VectorCopy( ent->s.origin, timer->s.origin ); // for z-sorting if( /*( ( item->type != IT_POWERUP ) && */GS_TeamBasedGametype() ) { edict_t *base; // what follows is basically a hack that allows timers to be assigned // to different teams in CTF. Powerups remain unassigned though base = G_ClosestFlagBase( ent ); if( base ) timer->s.modelindex = base->s.team; } timer->s.modelindex++; // add + 1 so we're guaranteed to have modelindex > 0 return timer; }
/* * G_Teams_TDM_UpdateTeamInfoMessages */ void G_Teams_UpdateTeamInfoMessages( void ) { static int nexttime = 0; static char teammessage[MAX_STRING_CHARS]; edict_t *ent, *e; size_t len; int i, j, team; char entry[MAX_TOKEN_CHARS]; int locationTag; nexttime -= game.snapFrameTime; if( nexttime > 0 ) return; while( nexttime <= 0 ) nexttime += 2000; // time for a new update for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ ) { *teammessage = 0; Q_snprintfz( teammessage, sizeof( teammessage ), "ti \"" ); len = strlen( teammessage ); // add our team info to the string for( i = 0; i < teamlist[team].numplayers; i++ ) { ent = game.edicts + teamlist[team].playerIndices[i]; if( G_IsDead( ent ) ) // don't show dead players continue; if( ent->r.client->teamstate.is_coach ) // don't show coachs continue; // get location name locationTag = G_MapLocationTAGForOrigin( ent->s.origin ); if( locationTag == -1 ) continue; *entry = 0; Q_snprintfz( entry, sizeof( entry ), "%i %i %i %i ", PLAYERNUM( ent ), locationTag, HEALTH_TO_INT( ent->health ), ARMOR_TO_INT( ent->r.client->resp.armor ) ); if( MAX_STRING_CHARS - len > strlen( entry ) ) { Q_strncatz( teammessage, entry, sizeof( teammessage ) ); len = strlen( teammessage ); } } // add closing quote *entry = 0; Q_snprintfz( entry, sizeof( entry ), "\"" ); if( MAX_STRING_CHARS - len > strlen( entry ) ) { Q_strncatz( teammessage, entry, sizeof( teammessage ) ); len = strlen( teammessage ); } for( i = 0; i < teamlist[team].numplayers; i++ ) { ent = game.edicts + teamlist[team].playerIndices[i]; if( !ent->r.inuse || !ent->r.client ) continue; trap_GameCmd( ent, teammessage ); // see if there are spectators chasing this player and send them the layout too for( j = 0; j < teamlist[TEAM_SPECTATOR].numplayers; j++ ) { e = game.edicts + teamlist[TEAM_SPECTATOR].playerIndices[j]; if( !e->r.inuse || !e->r.client ) continue; if( e->r.client->resp.chase.active && e->r.client->resp.chase.target == ENTNUM( ent ) ) trap_GameCmd( e, teammessage ); } } } }
static void Say_Team_Point_Location( edict_t *who, char *buf, int buflen, const char *current_color ) { G_MapLocationNameForTAG( G_MapLocationTAGForOrigin( point_location ), buf, buflen ); Q_strncatz( buf, current_color, buflen ); }