📄 g_team.c
字号:
================
Team_CheckHurtCarrier
Check to see if attacker hurt the flag carrier. Needed when handing out bonuses for assistance to flag
carrier defense.
================
*/
void Team_CheckHurtCarrier(gentity_t *targ, gentity_t *attacker)
{
int flag_pw;
if (!targ->client || !attacker->client)
return;
if (targ->client->sess.sessionTeam == TEAM_RED)
flag_pw = PW_BLUEFLAG;
else
flag_pw = PW_REDFLAG;
// flags
if (targ->client->ps.powerups[flag_pw] &&
targ->client->sess.sessionTeam != attacker->client->sess.sessionTeam)
attacker->client->pers.teamState.lasthurtcarrier = level.time;
// skulls
if (targ->client->ps.generic1 &&
targ->client->sess.sessionTeam != attacker->client->sess.sessionTeam)
attacker->client->pers.teamState.lasthurtcarrier = level.time;
}
gentity_t *Team_ResetFlag( int team ) {
char *c;
gentity_t *ent, *rent = NULL;
switch (team) {
case TEAM_RED:
c = "team_CTF_redflag";
break;
case TEAM_BLUE:
c = "team_CTF_blueflag";
break;
case TEAM_FREE:
c = "team_CTF_neutralflag";
break;
default:
return NULL;
}
ent = NULL;
while ((ent = G_Find (ent, FOFS(classname), c)) != NULL) {
if (ent->flags & FL_DROPPED_ITEM)
G_FreeEntity(ent);
else {
rent = ent;
RespawnItem(ent);
}
}
Team_SetFlagStatus( team, FLAG_ATBASE );
return rent;
}
void Team_ResetFlags( void ) {
if( g_gametype.integer == GT_CTF ) {
Team_ResetFlag( TEAM_RED );
Team_ResetFlag( TEAM_BLUE );
}
#ifdef MISSIONPACK
else if( g_gametype.integer == GT_1FCTF ) {
Team_ResetFlag( TEAM_FREE );
}
#endif
}
void Team_ReturnFlagSound( gentity_t *ent, int team ) {
gentity_t *te;
if (ent == NULL) {
G_Printf ("Warning: NULL passed to Team_ReturnFlagSound\n");
return;
}
te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_TEAM_SOUND );
if( team == TEAM_BLUE ) {
te->s.eventParm = GTS_RED_RETURN;
}
else {
te->s.eventParm = GTS_BLUE_RETURN;
}
te->r.svFlags |= SVF_BROADCAST;
}
void Team_TakeFlagSound( gentity_t *ent, int team ) {
gentity_t *te;
if (ent == NULL) {
G_Printf ("Warning: NULL passed to Team_TakeFlagSound\n");
return;
}
// only play sound when the flag was at the base
// or not picked up the last 10 seconds
switch(team) {
case TEAM_RED:
if( teamgame.blueStatus != FLAG_ATBASE ) {
if (teamgame.blueTakenTime > level.time - 10000)
return;
}
teamgame.blueTakenTime = level.time;
break;
case TEAM_BLUE: // CTF
if( teamgame.redStatus != FLAG_ATBASE ) {
if (teamgame.redTakenTime > level.time - 10000)
return;
}
teamgame.redTakenTime = level.time;
break;
}
te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_TEAM_SOUND );
if( team == TEAM_BLUE ) {
te->s.eventParm = GTS_RED_TAKEN;
}
else {
te->s.eventParm = GTS_BLUE_TAKEN;
}
te->r.svFlags |= SVF_BROADCAST;
}
void Team_CaptureFlagSound( gentity_t *ent, int team ) {
gentity_t *te;
if (ent == NULL) {
G_Printf ("Warning: NULL passed to Team_CaptureFlagSound\n");
return;
}
te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_TEAM_SOUND );
if( team == TEAM_BLUE ) {
te->s.eventParm = GTS_BLUE_CAPTURE;
}
else {
te->s.eventParm = GTS_RED_CAPTURE;
}
te->r.svFlags |= SVF_BROADCAST;
}
void Team_ReturnFlag( int team ) {
Team_ReturnFlagSound(Team_ResetFlag(team), team);
if( team == TEAM_FREE ) {
PrintMsg(NULL, "The flag has returned!\n" );
}
else {
PrintMsg(NULL, "The %s flag has returned!\n", TeamName(team));
}
}
void Team_FreeEntity( gentity_t *ent ) {
if( ent->item->giTag == PW_REDFLAG ) {
Team_ReturnFlag( TEAM_RED );
}
else if( ent->item->giTag == PW_BLUEFLAG ) {
Team_ReturnFlag( TEAM_BLUE );
}
else if( ent->item->giTag == PW_NEUTRALFLAG ) {
Team_ReturnFlag( TEAM_FREE );
}
}
/*
==============
Team_DroppedFlagThink
Automatically set in Launch_Item if the item is one of the flags
Flags are unique in that if they are dropped, the base flag must be respawned when they time out
==============
*/
void Team_DroppedFlagThink(gentity_t *ent) {
int team = TEAM_FREE;
if( ent->item->giTag == PW_REDFLAG ) {
team = TEAM_RED;
}
else if( ent->item->giTag == PW_BLUEFLAG ) {
team = TEAM_BLUE;
}
else if( ent->item->giTag == PW_NEUTRALFLAG ) {
team = TEAM_FREE;
}
Team_ReturnFlagSound( Team_ResetFlag( team ), team );
// Reset Flag will delete this entity
}
/*
==============
Team_DroppedFlagThink
==============
*/
int Team_TouchOurFlag( gentity_t *ent, gentity_t *other, int team ) {
int i;
gentity_t *player;
gclient_t *cl = other->client;
int enemy_flag;
#ifdef MISSIONPACK
if( g_gametype.integer == GT_1FCTF ) {
enemy_flag = PW_NEUTRALFLAG;
}
else {
#endif
if (cl->sess.sessionTeam == TEAM_RED) {
enemy_flag = PW_BLUEFLAG;
} else {
enemy_flag = PW_REDFLAG;
}
if ( ent->flags & FL_DROPPED_ITEM ) {
// hey, its not home. return it by teleporting it back
PrintMsg( NULL, "%s" S_COLOR_WHITE " returned the %s flag!\n",
cl->pers.netname, TeamName(team));
AddScore(other, ent->r.currentOrigin, CTF_RECOVERY_BONUS);
other->client->pers.teamState.flagrecovery++;
other->client->pers.teamState.lastreturnedflag = level.time;
//ResetFlag will remove this entity! We must return zero
Team_ReturnFlagSound(Team_ResetFlag(team), team);
return 0;
}
#ifdef MISSIONPACK
}
#endif
// the flag is at home base. if the player has the enemy
// flag, he's just won!
if (!cl->ps.powerups[enemy_flag])
return 0; // We don't have the flag
#ifdef MISSIONPACK
if( g_gametype.integer == GT_1FCTF ) {
PrintMsg( NULL, "%s" S_COLOR_WHITE " captured the flag!\n", cl->pers.netname );
}
else {
#endif
PrintMsg( NULL, "%s" S_COLOR_WHITE " captured the %s flag!\n", cl->pers.netname, TeamName(OtherTeam(team)));
#ifdef MISSIONPACK
}
#endif
cl->ps.powerups[enemy_flag] = 0;
teamgame.last_flag_capture = level.time;
teamgame.last_capture_team = team;
// Increase the team's score
AddTeamScore(ent->s.pos.trBase, other->client->sess.sessionTeam, 1);
Team_ForceGesture(other->client->sess.sessionTeam);
other->client->pers.teamState.captures++;
// add the sprite over the player's head
other->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
other->client->ps.eFlags |= EF_AWARD_CAP;
other->client->rewardTime = level.time + REWARD_SPRITE_TIME;
other->client->ps.persistant[PERS_CAPTURES]++;
// other gets another 10 frag bonus
AddScore(other, ent->r.currentOrigin, CTF_CAPTURE_BONUS);
Team_CaptureFlagSound( ent, team );
// Ok, let's do the player loop, hand out the bonuses
for (i = 0; i < g_maxclients.integer; i++) {
player = &g_entities[i];
if (!player->inuse)
continue;
if (player->client->sess.sessionTeam !=
cl->sess.sessionTeam) {
player->client->pers.teamState.lasthurtcarrier = -5;
} else if (player->client->sess.sessionTeam ==
cl->sess.sessionTeam) {
if (player != other)
AddScore(player, ent->r.currentOrigin, CTF_TEAM_BONUS);
// award extra points for capture assists
if (player->client->pers.teamState.lastreturnedflag +
CTF_RETURN_FLAG_ASSIST_TIMEOUT > level.time) {
AddScore (player, ent->r.currentOrigin, CTF_RETURN_FLAG_ASSIST_BONUS);
other->client->pers.teamState.assists++;
player->client->ps.persistant[PERS_ASSIST_COUNT]++;
// add the sprite over the player's head
player->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
player->client->ps.eFlags |= EF_AWARD_ASSIST;
player->client->rewardTime = level.time + REWARD_SPRITE_TIME;
} else if (player->client->pers.teamState.lastfraggedcarrier +
CTF_FRAG_CARRIER_ASSIST_TIMEOUT > level.time) {
AddScore(player, ent->r.currentOrigin, CTF_FRAG_CARRIER_ASSIST_BONUS);
other->client->pers.teamState.assists++;
player->client->ps.persistant[PERS_ASSIST_COUNT]++;
// add the sprite over the player's head
player->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
player->client->ps.eFlags |= EF_AWARD_ASSIST;
player->client->rewardTime = level.time + REWARD_SPRITE_TIME;
}
}
}
Team_ResetFlags();
CalculateRanks();
return 0; // Do not respawn this automatically
}
int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) {
gclient_t *cl = other->client;
#ifdef MISSIONPACK
if( g_gametype.integer == GT_1FCTF ) {
PrintMsg (NULL, "%s" S_COLOR_WHITE " got the flag!\n", other->client->pers.netname );
cl->ps.powerups[PW_NEUTRALFLAG] = INT_MAX; // flags never expire
if( team == TEAM_RED ) {
Team_SetFlagStatus( TEAM_FREE, FLAG_TAKEN_RED );
}
else {
Team_SetFlagStatus( TEAM_FREE, FLAG_TAKEN_BLUE );
}
}
else{
#endif
PrintMsg (NULL, "%s" S_COLOR_WHITE " got the %s flag!\n",
other->client->pers.netname, TeamName(team));
if (team == TEAM_RED)
cl->ps.powerups[PW_REDFLAG] = INT_MAX; // flags never expire
else
cl->ps.powerups[PW_BLUEFLAG] = INT_MAX; // flags never expire
Team_SetFlagStatus( team, FLAG_TAKEN );
#ifdef MISSIONPACK
}
#endif
AddScore(other, ent->r.currentOrigin, CTF_FLAG_BONUS);
cl->pers.teamState.flagsince = level.time;
Team_TakeFlagSound( ent, team );
return -1; // Do not respawn this automatically, but do delete it if it was FL_DROPPED
}
int Pickup_Team( gentity_t *ent, gentity_t *other ) {
int team;
gclient_t *cl = other->client;
#ifdef MISSIONPACK
if( g_gametype.integer == GT_OBELISK ) {
// there are no team items that can be picked up in obelisk
G_FreeEntity( ent );
return 0;
}
if( g_gametype.integer == GT_HARVESTER ) {
// the only team items that can be picked up in harvester are the cubes
if( ent->spawnflags != cl->sess.sessionTeam ) {
cl->ps.generic1 += 1;
}
G_FreeEntity( ent );
return 0;
}
#endif
// figure out what team this flag is
if( strcmp(ent->classname, "team_CTF_redflag") == 0 ) {
team = TEAM_RED;
}
else if( strcmp(ent->classname, "team_CTF_blueflag") == 0 ) {
team = TEAM_BLUE;
}
#ifdef MISSIONPACK
else if( strcmp(ent->classname, "team_CTF_neutralflag") == 0 ) {
team = TEAM_FREE;
}
#endif
else {
PrintMsg ( other, "Don't know what team the flag is on.\n");
return 0;
}
#ifdef MISSIONPACK
if( g_gametype.integer == GT_1FCTF ) {
if( team == TEAM_FREE ) {
return Team_TouchEnemyFlag( ent, other, cl->sess.sessionTeam );
}
if( team != cl->sess.sessionTeam) {
return Team_TouchOurFlag( ent, other, cl->sess.sessionTeam );
}
return 0;
}
#endif
// GT_CTF
if( team == cl->sess.sessionTeam) {
return Team_TouchOurFlag( ent, other, team );
}
return Team_TouchEnemyFlag( ent, other, team );
}
/*
===========
Team_GetLocation
Report a location for the player. Uses placed nearby target_location entities
============
*/
gentity_t *Team_GetLocation(gentity_t *ent)
{
gentity_t *eloc, *best;
float bestlen, len;
vec3_t origin;
best = NULL;
bestlen = 3*8192.0*8192.0;
VectorCopy( ent->r.currentOrigin, origin );
for (eloc = level.locationHead; eloc; eloc = eloc->nextTrain) {
len = ( origin[0] - eloc->r.currentOrigin[0] ) * ( origin[0] - eloc->r.currentOrigin[0] )
+ ( origin[1] - eloc->r.currentOrigin[1] ) * ( origin[1] - eloc->r.currentOrigin[1] )
+ ( origin[2] - eloc->r.currentOrigin[2] ) * ( origin[2] - eloc->r.currentOrigin[2] );
if ( len > bestlen ) {
continue;
}
if ( !trap_InPVS( origin, eloc->r.currentOrigin ) ) {
continue;
}
bestlen = len;
best = eloc;
}
return best;
}
/*
===========
Team_GetLocation
Report a location for the player. Uses placed nearby target_location entities
============
*/
qboolean Team_GetLocationMsg(gentity_t *ent, char *loc, int loclen)
{
gentity_t *best;
best = Team_GetLocation( ent );
if (!best)
return qfalse;
if (best->count) {
if (best->count < 0)
best->count = 0;
if (best->count > 7)
best->count = 7;
Com_sprintf(loc, loclen, "%c%c%s" S_COLOR_WHITE, Q_COLOR_ESCAPE, best->count + '0', best->message );
} else
Com_sprintf(loc, loclen, "%s", best->message);
return qtrue;
}
/*---------------------------------------------------------------------------*/
/*
================
SelectRandomDeathmatchSpawnPoint
go to a random point that doesn't telefrag
================
*/
#define MAX_TEAM_SPAWN_POINTS 32
gentity_t *SelectRandomTeamSpawnPoint( int teamstate, team_t team ) {
gentity_t *spot;
int count;
int selection;
gentity_t *spots[MAX_TEAM_SPAWN_POINTS];
char *classname;
if (teamstate == TEAM_BEGIN) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -