void Team_ReturnFlag(gentity_t *ent) { int team = ent->item->giTag == PW_REDFLAG ? TEAM_AXIS : TEAM_ALLIES; Team_ReturnFlagSound(ent, team); Team_ResetFlag(ent); PrintMsg(NULL, "The %s flag has returned!\n", TeamName(team)); }
int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) { gclient_t *cl = other->client; if( g_gametype.integer == GT_1FCTF ) { PrintMsg (NULL, "%s" S_COLOR_WHITE " got the flag!\n", other->client->pers.netname ); if( team == TEAM_RED ) { Team_SetFlagStatus( TEAM_FREE, FLAG_TAKEN_RED ); } else { Team_SetFlagStatus( TEAM_FREE, FLAG_TAKEN_BLUE ); } } else{ PrintMsg (NULL, "%s" S_COLOR_WHITE " got the %s flag!\n", other->client->pers.netname, TeamName(team)); Team_SetFlagStatus( team, FLAG_TAKEN ); } 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 Team_TouchEnemyFlag(Gentity *ent, Gentity *other, int team) { Gclient *cl = other->client; 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{ 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); } 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 */ }
/** * @brief Team_ReturnFlag * @param[in] ent */ void Team_ReturnFlag(gentity_t *ent) { int team = ent->item->giTag == PW_REDFLAG ? TEAM_AXIS : TEAM_ALLIES; Team_ReturnFlagSound(ent, team); Team_ResetFlag(ent); PrintMsg(NULL, "The %s flag has returned!\n", TeamName(team)); // FIXME: returns RED/BLUE flag ... change to Axis/Allies? }
void Team_ReturnFlag( int team ) { Team_ReturnFlagSound(Team_ResetFlag(team), team); if( team == TEAM_FREE ) { PrintMsg(NULL, "The lolly has returned!\n" ); } else { PrintMsg(NULL, "The %s lolly has returned!\n", TeamName(team)); } }
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)); }
// TODO: Draw a ScorePlum() as well? Needs cgame fixes to draw plum regardless of "owner" void AddTeamScore( vec3_t origin, int team, int score, char *reason ) { gentity_t *te; te = G_TempEntity(origin, EV_GLOBAL_TEAM_SOUND ); te->r.svFlags |= SVF_BROADCAST; if ( team == TEAM_RED ) { if ( level.teamScores[ TEAM_RED ] + score == level.teamScores[ TEAM_BLUE ] ) { //teams are tied sound te->s.eventParm = GTS_TEAMS_ARE_TIED; } else if ( level.teamScores[ TEAM_RED ] <= level.teamScores[ TEAM_BLUE ] && level.teamScores[ TEAM_RED ] + score > level.teamScores[ TEAM_BLUE ]) { // red took the lead sound te->s.eventParm = GTS_REDTEAM_TOOK_LEAD; } else { // red scored sound te->s.eventParm = GTS_REDTEAM_SCORED; // Hackity! In BB teams score continously, which makes for annoying // sound spam. Thus disable sound. // Better solution would be to either only do this sound on captures/destroys // or continously at fixed time offsets. // Also note that there already is a "blue/red balloon" sound in cgame CG_UpdateBalloonStates if ( g_gametype.integer == GT_BALLOON ) { G_FreeEntity( te ); } } } else { if ( level.teamScores[ TEAM_BLUE ] + score == level.teamScores[ TEAM_RED ] ) { //teams are tied sound te->s.eventParm = GTS_TEAMS_ARE_TIED; } else if ( level.teamScores[ TEAM_BLUE ] <= level.teamScores[ TEAM_RED ] && level.teamScores[ TEAM_BLUE ] + score > level.teamScores[ TEAM_RED ]) { // blue took the lead sound te->s.eventParm = GTS_BLUETEAM_TOOK_LEAD; } else { // blue scored sound te->s.eventParm = GTS_BLUETEAM_SCORED; // See note above if ( g_gametype.integer == GT_BALLOON ) { G_FreeEntity( te ); } } } level.teamScores[ team ] += score; CalculateRanks(); G_LogPrintf( "AddTeamScore: %s %i %s\n", TeamName( team ), score, reason ); }
int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) { gclient_t *cl = other->client; // hey, its not our flag, pick it up PrintMsg( NULL, "%s" S_COLOR_WHITE " got the %s flag!\n", other->client->pers.netname, TeamName( team ) ); AddScore( other, CTF_FLAG_BONUS ); 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 } cl->pers.teamState.flagsince = level.time; return -1; // Do not respawn this automatically, but do delete it if it was FL_DROPPED }
int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) { gclient_t *cl = other->client; PrintMsg (NULL, "%s" S_COLOR_WHITE " got the %s lolly!\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 ); AddScore( other, ent->r.currentOrigin, CTF_FLAG_BONUS, SCORE_BONUS_FLAG_S ); 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 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, 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 }
/* ================ G_TeamCommand Broadcasts a command to only a specific team ================ */ void G_TeamCommand( team_t team, char *cmd ) { gconnection_t *connection; int i, j, clientNum; for ( i = 0 ; i < level.maxconnections ; i++ ) { connection = &level.connections[i]; for ( j = 0; j < MAX_SPLITVIEW; j++ ) { clientNum = connection->localPlayerNums[j]; if ( level.clients[clientNum].sess.sessionTeam == team ) break; } if ( j < MAX_SPLITVIEW ) { // Include team when there are multiple local players if ( connection->numLocalPlayers > 1 ) { trap_SendServerCommandEx( i, -1, va( "[%s] %s", TeamName( team ), cmd ) ); } else { trap_SendServerCommand( i, cmd ); } } } }
/* * Team_FragBonuses * * Calculate the bonuses for flag defense, flag carrier defense, etc. * Note that bonuses are not cumulative. You get one, they are in importance * order. */ void Team_FragBonuses(Gentity *targ, Gentity *inflictor, Gentity *attacker) { int i; Gentity *ent; int flag_pw, enemy_flag_pw; int otherteam; int tokens; Gentity *flag, *carrier = NULL; char *c; Vec3 v1, v2; int team; /* no bonus for fragging yourself or team mates */ if(!targ->client || !attacker->client || targ == attacker || OnSameTeam(targ, attacker)) return; team = targ->client->sess.team; otherteam = OtherTeam(targ->client->sess.team); if(otherteam < 0) return; /* whoever died isn't on a team */ /* same team, if the flag at base, check to he has the enemy flag */ if(team == TEAM_RED){ flag_pw = PW_REDFLAG; enemy_flag_pw = PW_BLUEFLAG; }else{ flag_pw = PW_BLUEFLAG; enemy_flag_pw = PW_REDFLAG; } if(g_gametype.integer == GT_1FCTF) enemy_flag_pw = PW_NEUTRALFLAG; /* did the attacker frag the flag carrier? */ tokens = 0; if(targ->client->ps.powerups[enemy_flag_pw]){ attacker->client->pers.teamState.lastfraggedcarrier = level.time; AddScore(attacker, targ->r.currentOrigin, CTF_FRAG_CARRIER_BONUS); attacker->client->pers.teamState.fragcarrier++; PrintMsg(NULL, "%s" S_COLOR_WHITE " fragged %s's flag carrier!\n", attacker->client->pers.netname, TeamName( team)); /* the target had the flag, clear the hurt carrier * field on the other team */ for(i = 0; i < g_maxclients.integer; i++){ ent = g_entities + i; if(ent->inuse && ent->client->sess.team == otherteam) ent->client->pers.teamState.lasthurtcarrier = 0; } return; } /* did the attacker frag a head carrier? other->client->ps.generic1 */ if(tokens){ attacker->client->pers.teamState.lastfraggedcarrier = level.time; AddScore(attacker, targ->r.currentOrigin, CTF_FRAG_CARRIER_BONUS * tokens * tokens); attacker->client->pers.teamState.fragcarrier++; PrintMsg(NULL, "%s" S_COLOR_WHITE " fragged %s's skull carrier!\n", attacker->client->pers.netname, TeamName( team)); /* the target had the flag, clear the hurt carrier * field on the other team */ for(i = 0; i < g_maxclients.integer; i++){ ent = g_entities + i; if(ent->inuse && ent->client->sess.team == otherteam) ent->client->pers.teamState.lasthurtcarrier = 0; } return; } if(targ->client->pers.teamState.lasthurtcarrier && level.time - targ->client->pers.teamState.lasthurtcarrier < CTF_CARRIER_DANGER_PROTECT_TIMEOUT && !attacker->client->ps.powerups[flag_pw]){ /* attacker is on the same team as the flag carrier and * fragged a guy who hurt our flag carrier */ AddScore(attacker, targ->r.currentOrigin, CTF_CARRIER_DANGER_PROTECT_BONUS); attacker->client->pers.teamState.carrierdefense++; targ->client->pers.teamState.lasthurtcarrier = 0; attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; /* add the sprite over the player's head */ attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP); attacker->client->ps.eFlags |= EF_AWARD_DEFEND; attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME; return; } if(targ->client->pers.teamState.lasthurtcarrier && level.time - targ->client->pers.teamState.lasthurtcarrier < CTF_CARRIER_DANGER_PROTECT_TIMEOUT){ /* attacker is on the same team as the skull carrier and */ AddScore(attacker, targ->r.currentOrigin, CTF_CARRIER_DANGER_PROTECT_BONUS); attacker->client->pers.teamState.carrierdefense++; targ->client->pers.teamState.lasthurtcarrier = 0; attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; /* add the sprite over the player's head */ attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP); attacker->client->ps.eFlags |= EF_AWARD_DEFEND; attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME; return; } /* flag and flag carrier area defense bonuses */ /* we have to find the flag and carrier entities */ /* find the flag */ switch(attacker->client->sess.team){ case TEAM_RED: c = "team_CTF_redflag"; break; case TEAM_BLUE: c = "team_CTF_blueflag"; break; default: return; } /* find attacker's team's flag carrier */ for(i = 0; i < g_maxclients.integer; i++){ carrier = g_entities + i; if(carrier->inuse && carrier->client->ps.powerups[flag_pw]) break; carrier = NULL; } flag = NULL; while((flag = G_Find (flag, FOFS(classname), c)) != NULL) if(!(flag->flags & FL_DROPPED_ITEM)) break; if(!flag) return; /* can't find attacker's flag */ /* ok we have the attackers flag and a pointer to the carrier */ /* check to see if we are defending the base's flag */ subv3(targ->r.currentOrigin, flag->r.currentOrigin, v1); subv3(attacker->r.currentOrigin, flag->r.currentOrigin, v2); if(((lenv3(v1) < CTF_TARGET_PROTECT_RADIUS && trap_InPVS(flag->r.currentOrigin, targ->r.currentOrigin)) || (lenv3(v2) < CTF_TARGET_PROTECT_RADIUS && trap_InPVS(flag->r.currentOrigin, attacker->r.currentOrigin))) && attacker->client->sess.team != targ->client->sess.team){ /* we defended the base flag */ AddScore(attacker, targ->r.currentOrigin, CTF_FLAG_DEFENSE_BONUS); attacker->client->pers.teamState.basedefense++; attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; /* add the sprite over the player's head */ attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP); attacker->client->ps.eFlags |= EF_AWARD_DEFEND; attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME; return; } if(carrier && carrier != attacker){ subv3(targ->r.currentOrigin, carrier->r.currentOrigin, v1); subv3(attacker->r.currentOrigin, carrier->r.currentOrigin, v1); if(((lenv3(v1) < CTF_ATTACKER_PROTECT_RADIUS && trap_InPVS(carrier->r.currentOrigin, targ->r.currentOrigin)) || (lenv3(v2) < CTF_ATTACKER_PROTECT_RADIUS && trap_InPVS(carrier->r.currentOrigin, attacker->r.currentOrigin))) && attacker->client->sess.team != targ->client->sess.team){ AddScore(attacker, targ->r.currentOrigin, CTF_CARRIER_PROTECT_BONUS); attacker->client->pers.teamState.carrierdefense++; attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; /* add the sprite over the player's head */ attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP); attacker->client->ps.eFlags |= EF_AWARD_DEFEND; attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME; return; } } }
/* ======================================================================================================================================= Team_TouchOurFlag ======================================================================================================================================= */ int Team_TouchOurFlag(gentity_t *ent, gentity_t *other, int team) { int i; gentity_t *player; gclient_t *cl = other->client; int enemy_flag; if (g_gametype.integer == GT_1FCTF) { enemy_flag = PW_NEUTRALFLAG; } else { if (cl->sess.sessionTeam == TEAM_RED) { enemy_flag = PW_BLUEFLAG; } else { enemy_flag = PW_REDFLAG; } if (ent->flags & FL_DROPPED_ITEM) { // hey, it's 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.lastreturnedflag = level.time; // 'ResetFlag' will remove this entity! We must return zero Team_ReturnFlagSound(Team_ResetFlag(team), team); return 0; } } // 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 } if (g_gametype.integer == GT_1FCTF) { trap_SendServerCommand(-1, va("cp \"%s" S_COLOR_WHITE "\ncaptured the flag!\n\"", cl->pers.netname)); } else { trap_SendServerCommand(-1, va("cp \"%s" S_COLOR_WHITE "\ncaptured the %s flag!\n\"", cl->pers.netname, TeamName(OtherTeam(team)))); } cl->ps.powerups[enemy_flag] = 0; other->client->rewardTime = level.time + REWARD_TIME; other->client->ps.persistant[PERS_CAPTURES]++; // other gets another 10 frag bonus AddScore(other, ent->r.currentOrigin, CTF_CAPTURE_BONUS); // ok, let's do the player loop, hand out the bonuses for (i = 0; i < g_maxclients.integer; i++) { player = &g_entities[i]; // also make sure we don't award assist bonuses to the flag carrier himself. if (!player->inuse || player == other) { continue; } if (player->client->sess.sessionTeam != cl->sess.sessionTeam) { player->client->pers.teamState.lasthurtcarrier = -5; } else if (player->client->sess.sessionTeam == cl->sess.sessionTeam) { 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); player->client->ps.persistant[PERS_ASSIST_COUNT]++; player->client->rewardTime = level.time + REWARD_TIME; } if (player->client->pers.teamState.lastfraggedcarrier + CTF_FRAG_CARRIER_ASSIST_TIMEOUT > level.time) { AddScore(player, ent->r.currentOrigin, CTF_FRAG_CARRIER_ASSIST_BONUS); player->client->ps.persistant[PERS_ASSIST_COUNT]++; player->client->rewardTime = level.time + REWARD_TIME; } } } 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); CalculateRanks(); Team_ResetFlags(); Team_CaptureFlagSound(ent, team); Team_ForceGesture(other->client->sess.sessionTeam); return 0; // do not respawn this automatically }
/* ======================================================================================================================================= Team_FragBonuses Calculate the bonuses for flag defense, flag carrier defense, etc. Note that bonuses are not cumulative. You get one, they are in importance order. ======================================================================================================================================= */ void Team_FragBonuses(gentity_t *targ, gentity_t *inflictor, gentity_t *attacker) { int i; gentity_t *ent; int flag_pw, enemy_flag_pw; int otherteam; gentity_t *flag, *carrier = NULL; char *c; vec3_t v1, v2; int team; // no bonus for fragging yourself or team mates if (!targ->client || !attacker->client || targ == attacker || OnSameTeam(targ, attacker)) { return; } team = targ->client->sess.sessionTeam; otherteam = OtherTeam(targ->client->sess.sessionTeam); if (otherteam < 0) { return; // whoever died isn't on a team } // same team, if the flag at base, check to he has the enemy flag if (team == TEAM_RED) { flag_pw = PW_REDFLAG; enemy_flag_pw = PW_BLUEFLAG; } else { flag_pw = PW_BLUEFLAG; enemy_flag_pw = PW_REDFLAG; } if (g_gametype.integer == GT_1FCTF) { flag_pw = PW_NEUTRALFLAG; enemy_flag_pw = PW_NEUTRALFLAG; } // did the attacker frag the flag carrier? if (targ->client->ps.powerups[enemy_flag_pw]) { attacker->client->pers.teamState.lastfraggedcarrier = level.time; AddScore(attacker, targ->r.currentOrigin, CTF_FRAG_CARRIER_BONUS); PrintMsg(NULL, "%s" S_COLOR_WHITE " fragged %s's flag carrier!\n", attacker->client->pers.netname, TeamName(team)); // the target had the flag, clear the hurt carrier field on the other team for (i = 0; i < g_maxclients.integer; i++) { ent = g_entities + i; if (ent->inuse && ent->client->sess.sessionTeam == otherteam) { ent->client->pers.teamState.lasthurtcarrier = 0; } } return; } // did the attacker frag a skull carrier? if (g_gametype.integer == GT_HARVESTER && targ->client->ps.tokens) { int tokens = targ->client->ps.tokens; attacker->client->pers.teamState.lastfraggedcarrier = level.time; AddScore(attacker, targ->r.currentOrigin, CTF_FRAG_CARRIER_BONUS * tokens * tokens); PrintMsg(NULL, "%s" S_COLOR_WHITE " fragged %s's skull carrier!\n", attacker->client->pers.netname, TeamName(team)); // the target had the flag, clear the hurt carrier field on the other team for (i = 0; i < g_maxclients.integer; i++) { ent = g_entities + i; if (ent->inuse && ent->client->sess.sessionTeam == otherteam) { ent->client->pers.teamState.lasthurtcarrier = 0; } } return; } if (targ->client->pers.teamState.lasthurtcarrier && level.time - targ->client->pers.teamState.lasthurtcarrier < CTF_CARRIER_DANGER_PROTECT_TIMEOUT && !attacker->client->ps.powerups[flag_pw]) { // attacker is on the same team as the flag carrier and fragged a guy who hurt our flag carrier AddScore(attacker, targ->r.currentOrigin, CTF_CARRIER_DANGER_PROTECT_BONUS); targ->client->pers.teamState.lasthurtcarrier = 0; attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; attacker->client->rewardTime = level.time + REWARD_TIME; return; } // flag and flag carrier area defense bonuses // we have to find the flag and carrier entities if (g_gametype.integer == GT_OBELISK) { // find the team obelisk switch (attacker->client->sess.sessionTeam) { case TEAM_RED: c = "team_redobelisk"; break; case TEAM_BLUE: c = "team_blueobelisk"; break; default: return; } } else if (g_gametype.integer == GT_HARVESTER) { // find the center obelisk c = "team_neutralobelisk"; } else { // find the flag switch (attacker->client->sess.sessionTeam) { case TEAM_RED: c = "team_CTF_redflag"; break; case TEAM_BLUE: c = "team_CTF_blueflag"; break; default: return; } // find attacker's team's flag carrier for (i = 0; i < g_maxclients.integer; i++) { carrier = g_entities + i; if (carrier->inuse && carrier->client->ps.powerups[flag_pw]) { break; } carrier = NULL; } } flag = NULL; while ((flag = G_Find(flag, FOFS(classname), c)) != NULL) { if (!(flag->flags & FL_DROPPED_ITEM)) { break; } } if (!flag) { return; // can't find attacker's flag } // ok we have the attackers flag and a pointer to the carrier // check to see if we are defending the base's flag VectorSubtract(targ->r.currentOrigin, flag->r.currentOrigin, v1); VectorSubtract(attacker->r.currentOrigin, flag->r.currentOrigin, v2); if (((VectorLength(v1) < CTF_TARGET_PROTECT_RADIUS && trap_InPVS(flag->r.currentOrigin, targ->r.currentOrigin)) || (VectorLength(v2) < CTF_TARGET_PROTECT_RADIUS && trap_InPVS(flag->r.currentOrigin, attacker->r.currentOrigin))) && attacker->client->sess.sessionTeam != targ->client->sess.sessionTeam) { // we defended the base flag AddScore(attacker, targ->r.currentOrigin, CTF_FLAG_DEFENSE_BONUS); attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; attacker->client->rewardTime = level.time + REWARD_TIME; return; } if (carrier && carrier != attacker) { VectorSubtract(targ->r.currentOrigin, carrier->r.currentOrigin, v1); VectorSubtract(attacker->r.currentOrigin, carrier->r.currentOrigin, v2); if (((VectorLength(v1) < CTF_ATTACKER_PROTECT_RADIUS && trap_InPVS(carrier->r.currentOrigin, targ->r.currentOrigin)) || (VectorLength(v2) < CTF_ATTACKER_PROTECT_RADIUS && trap_InPVS(carrier->r.currentOrigin, attacker->r.currentOrigin))) && attacker->client->sess.sessionTeam != targ->client->sess.sessionTeam) { AddScore(attacker, targ->r.currentOrigin, CTF_CARRIER_PROTECT_BONUS); attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; attacker->client->rewardTime = level.time + REWARD_TIME; return; } } }
/* ======================================================================================================================================= ObeliskTouch ======================================================================================================================================= */ static void ObeliskTouch(gentity_t *self, gentity_t *other, trace_t *trace) { int tokens; team_t otherTeam; if (!other->client) { return; } otherTeam = OtherTeam(other->client->sess.sessionTeam); if (otherTeam != self->spawnflags) { return; } tokens = other->client->ps.tokens; if (tokens <= 0) { return; } trap_SendServerCommand(-1, va("cp \"%s" S_COLOR_WHITE "\nbrought in %i %s %s!\n\"", other->client->pers.netname, tokens, TeamName(otherTeam), (tokens == 1) ? "skull" : "skulls")); other->client->rewardTime = level.time + REWARD_TIME; other->client->ps.persistant[PERS_CAPTURES] += tokens; other->client->ps.tokens = 0; AddScore(other, self->r.currentOrigin, CTF_CAPTURE_BONUS * tokens); AddTeamScore(self->s.pos.trBase, other->client->sess.sessionTeam, tokens); CalculateRanks(); Team_CaptureFlagSound(self, self->spawnflags); Team_ForceGesture(other->client->sess.sessionTeam); }
/* ======================================================================================================================================= ObeliskDie ======================================================================================================================================= */ static void ObeliskDie(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod) { int otherTeam; otherTeam = OtherTeam(self->spawnflags); self->takedamage = qfalse; self->think = ObeliskRespawn; self->nextthink = level.time + g_obeliskRespawnDelay.integer * 1000; self->activator->s.modelindex2 = 0xff; self->activator->s.frame = 2; G_AddEvent(self->activator, EV_OBELISKEXPLODE, 0); if (self->spawnflags == attacker->client->sess.sessionTeam) { AddScore(attacker, self->r.currentOrigin, -CTF_CAPTURE_BONUS); } else { AddScore(attacker, self->r.currentOrigin, CTF_CAPTURE_BONUS); attacker->client->rewardTime = level.time + REWARD_TIME; attacker->client->ps.persistant[PERS_CAPTURES]++; } AddTeamScore(self->s.pos.trBase, otherTeam, 1); CalculateRanks(); Team_CaptureFlagSound(self, self->spawnflags); Team_ForceGesture(otherTeam); teamgame.redObeliskAttackedTime = 0; teamgame.blueObeliskAttackedTime = 0; trap_SendServerCommand(-1, va("cp \"%s" S_COLOR_WHITE "\ndestroyed the %s obelisk!\n\"", attacker->client->pers.netname, TeamName(self->spawnflags))); }
/* ================ Team_FragBonuses Calculate the bonuses for flag defense, flag carrier defense, etc. Note that bonuses are not cumulative. You get one, they are in importance order. ================ */ void Team_FragBonuses(gentity_t *targ, gentity_t *inflictor, gentity_t *attacker) { int i; gentity_t *ent; int flag_pw, enemy_flag_pw; int otherteam; int tokens; gentity_t *flag, *carrier = NULL; const char *c; bvec3_t v1, v2; int team; // no bonus for fragging yourself or team mates if (!targ->client || !attacker->client || targ == attacker || OnSameTeam(targ, attacker)) return; team = targ->client->sess.sessionTeam; otherteam = OtherTeam(targ->client->sess.sessionTeam); if (otherteam < 0) return; // whoever died isn't on a team // same team, if the flag at base, check to he has the enemy flag if (team == TEAM_RED) { flag_pw = PW_REDFLAG; enemy_flag_pw = PW_BLUEFLAG; } else { flag_pw = PW_BLUEFLAG; enemy_flag_pw = PW_REDFLAG; } if (g_gametype.integer == GT_1FCTF) { enemy_flag_pw = PW_NEUTRALFLAG; } // did the attacker frag the flag carrier? tokens = 0; #ifdef MISSIONPACK if( g_gametype.integer == GT_HARVESTER ) { tokens = targ->client->ps.generic1; } #endif if (targ->client->ps.powerups[enemy_flag_pw]) { attacker->client->pers.teamState.lastfraggedcarrier = MAKE_GFIXED(level.time); AddScore(attacker, targ->r.currentOrigin, CTF_FRAG_CARRIER_BONUS); attacker->client->pers.teamState.fragcarrier++; PrintMsg(NULL, "%s" S_COLOR_WHITE " fragged %s's flag carrier!\n", attacker->client->pers.netname, TeamName(team)); // the target had the flag, clear the hurt carrier // field on the other team for (i = 0; i < g_maxclients.integer; i++) { ent = g_entities + i; if (ent->inuse && ent->client->sess.sessionTeam == otherteam) ent->client->pers.teamState.lasthurtcarrier = GFIXED_0; } return; } // did the attacker frag a head carrier? other->client->ps.generic1 if (tokens) { attacker->client->pers.teamState.lastfraggedcarrier = MAKE_GFIXED(level.time); AddScore(attacker, targ->r.currentOrigin, CTF_FRAG_CARRIER_BONUS * tokens * tokens); attacker->client->pers.teamState.fragcarrier++; PrintMsg(NULL, "%s" S_COLOR_WHITE " fragged %s's skull carrier!\n", attacker->client->pers.netname, TeamName(team)); // the target had the flag, clear the hurt carrier // field on the other team for (i = 0; i < g_maxclients.integer; i++) { ent = g_entities + i; if (ent->inuse && ent->client->sess.sessionTeam == otherteam) ent->client->pers.teamState.lasthurtcarrier = GFIXED_0; } return; } if (FIXED_NOT_ZERO(targ->client->pers.teamState.lasthurtcarrier) && MAKE_GFIXED(level.time) - targ->client->pers.teamState.lasthurtcarrier < GFIXED(CTF_CARRIER_DANGER_PROTECT_TIMEOUT,0) && !attacker->client->ps.powerups[flag_pw]) { // attacker is on the same team as the flag carrier and // fragged a guy who hurt our flag carrier AddScore(attacker, targ->r.currentOrigin, CTF_CARRIER_DANGER_PROTECT_BONUS); attacker->client->pers.teamState.carrierdefense++; targ->client->pers.teamState.lasthurtcarrier = GFIXED_0; attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; team = attacker->client->sess.sessionTeam; // add the sprite over the player's head attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP ); attacker->client->ps.eFlags |= EF_AWARD_DEFEND; attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME; return; } if (FIXED_NOT_ZERO(targ->client->pers.teamState.lasthurtcarrier) && MAKE_GFIXED(level.time) - targ->client->pers.teamState.lasthurtcarrier < GFIXED(CTF_CARRIER_DANGER_PROTECT_TIMEOUT,0)) { // attacker is on the same team as the skull carrier and AddScore(attacker, targ->r.currentOrigin, CTF_CARRIER_DANGER_PROTECT_BONUS); attacker->client->pers.teamState.carrierdefense++; targ->client->pers.teamState.lasthurtcarrier = GFIXED_0; attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; team = attacker->client->sess.sessionTeam; // add the sprite over the player's head attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP ); attacker->client->ps.eFlags |= EF_AWARD_DEFEND; attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME; return; } // flag and flag carrier area defense bonuses // we have to find the flag and carrier entities #ifdef MISSIONPACK if( g_gametype.integer == GT_OBELISK ) { // find the team obelisk switch (attacker->client->sess.sessionTeam) { case TEAM_RED: c = "team_redobelisk"; break; case TEAM_BLUE: c = "team_blueobelisk"; break; default: return; } } else if (g_gametype.integer == GT_HARVESTER ) { // find the center obelisk c = "team_neutralobelisk"; } else { #endif // find the flag switch (attacker->client->sess.sessionTeam) { case TEAM_RED: c = "team_CTF_redflag"; break; case TEAM_BLUE: c = "team_CTF_blueflag"; break; default: return; } // find attacker's team's flag carrier for (i = 0; i < g_maxclients.integer; i++) { carrier = g_entities + i; if (carrier->inuse && carrier->client->ps.powerups[flag_pw]) break; carrier = NULL; } #ifdef MISSIONPACK } #endif flag = NULL; while ((flag = G_Find (flag, FOFS(classname), c)) != NULL) { if (!(flag->flags & FL_DROPPED_ITEM)) break; } if (!flag) return; // can't find attacker's flag // ok we have the attackers flag and a pointer to the carrier // check to see if we are defending the base's flag VectorSubtract(targ->r.currentOrigin, flag->r.currentOrigin, v1); VectorSubtract(attacker->r.currentOrigin, flag->r.currentOrigin, v2); if ( ( ( FIXED_VEC3LEN(v1) < BFIXED(CTF_TARGET_PROTECT_RADIUS,0) && _G_trap_InPVS(flag->r.currentOrigin, targ->r.currentOrigin ) ) || ( FIXED_VEC3LEN(v2) < BFIXED(CTF_TARGET_PROTECT_RADIUS,0) && _G_trap_InPVS(flag->r.currentOrigin, attacker->r.currentOrigin ) ) ) && attacker->client->sess.sessionTeam != targ->client->sess.sessionTeam) { // we defended the base flag AddScore(attacker, targ->r.currentOrigin, CTF_FLAG_DEFENSE_BONUS); attacker->client->pers.teamState.basedefense++; attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; // add the sprite over the player's head attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP ); attacker->client->ps.eFlags |= EF_AWARD_DEFEND; attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME; return; } if (carrier && carrier != attacker) { VectorSubtract(targ->r.currentOrigin, carrier->r.currentOrigin, v1); VectorSubtract(attacker->r.currentOrigin, carrier->r.currentOrigin, v1); if ( ( ( FIXED_VEC3LEN(v1) < BFIXED(CTF_ATTACKER_PROTECT_RADIUS,0) && _G_trap_InPVS(carrier->r.currentOrigin, targ->r.currentOrigin ) ) || ( FIXED_VEC3LEN(v2) < BFIXED(CTF_ATTACKER_PROTECT_RADIUS,0) && _G_trap_InPVS(carrier->r.currentOrigin, attacker->r.currentOrigin ) ) ) && attacker->client->sess.sessionTeam != targ->client->sess.sessionTeam) { AddScore(attacker, targ->r.currentOrigin, CTF_CARRIER_PROTECT_BONUS); attacker->client->pers.teamState.carrierdefense++; attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; // add the sprite over the player's head attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP ); attacker->client->ps.eFlags |= EF_AWARD_DEFEND; attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME; return; } } }
/* ============== 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 }
/* ============== 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; if (cl->sess.sessionTeam == TEAM_RED) { enemy_flag = PW_BLUEFLAG; } else { enemy_flag = PW_REDFLAG; } if ( ent->flags & FL_DROPPED_ITEM ) { // hey, it's not home. return it by teleporting it back PrintMsg( NULL, "%s" S_COLOR_WHITE " returned the %s lolly!\n", cl->pers.netname, TeamName( team ) ); AddScore( other, ent->r.currentOrigin, CTF_RECOVERY_BONUS, SCORE_BONUS_RECOVERY_S ); 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; } // 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 PrintMsg( NULL, "%s" S_COLOR_WHITE " captured the %s lolly!\n", cl->pers.netname, TeamName(OtherTeam(team))); 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, SCORE_CAPTURE, SCORE_BONUS_CAPTURE_S ); // Team_ForceGesture(other->client->sess.sessionTeam); other->client->pers.teamState.captures++; // add the sprite over the player's head SetAward( other->client, AWARD_CAP ); other->client->ps.persistant[PERS_CAPTURES]++; // other gets another 10 frag bonus AddScore( other, ent->r.currentOrigin, CTF_CAPTURE_BONUS, SCORE_BONUS_CAPTURE_S ); 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]; // also make sure we don't award assist bonuses to the flag carrier himself. if (!player->inuse || player == other) 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, SCORE_BONUS_CAPTURE_TEAM_S ); // 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, SCORE_BONUS_ASSIST_RETURN_S ); other->client->pers.teamState.assists++; player->client->ps.persistant[PERS_ASSIST_COUNT]++; // add the sprite over the player's head SetAward( player->client, AWARD_ASSIST ); } else if (player->client->pers.teamState.lastfraggedcarrier + CTF_FRAG_CARRIER_ASSIST_TIMEOUT > level.time) { AddScore( player, ent->r.currentOrigin, CTF_FRAG_CARRIER_ASSIST_BONUS, SCORE_BONUS_ASSIST_FRAG_CARRIER_S ); other->client->pers.teamState.assists++; player->client->ps.persistant[PERS_ASSIST_COUNT]++; // add the sprite over the player's head SetAward( player->client, AWARD_ASSIST ); } } } Team_ResetFlags(); return 0; // Do not respawn this automatically }
int Team_TouchOurFlag( gentity_t *ent, gentity_t *other, int team ) { int i; gentity_t *player; gclient_t *cl = other->client; int our_flag, enemy_flag; gentity_t *te; if ( cl->sess.sessionTeam == TEAM_RED ) { our_flag = PW_REDFLAG; enemy_flag = PW_BLUEFLAG; } else { our_flag = PW_BLUEFLAG; 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, 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; } // 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 } PrintMsg( NULL, "%s" S_COLOR_WHITE " captured the %s flag!\n", cl->pers.netname, TeamName( OtherTeam( team ) ) ); cl->ps.powerups[enemy_flag] = 0; teamgame.last_flag_capture = level.time; teamgame.last_capture_team = team; // Increase the team's score level.teamScores[ other->client->sess.sessionTeam ]++; other->client->pers.teamState.captures++; // other gets another 10 frag bonus AddScore( other, CTF_CAPTURE_BONUS ); te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_SOUND ); te->s.eventParm = G_SoundIndex( our_flag == PW_REDFLAG ? "sound/teamplay/flagcap_red.wav" : "sound/teamplay/flagcap_blu.wav" ); te->r.svFlags |= SVF_BROADCAST; // 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, CTF_CAPTURE_BONUS ); } // award extra points for capture assists if ( player->client->pers.teamState.lastreturnedflag + CTF_RETURN_FLAG_ASSIST_TIMEOUT > level.time ) { PrintMsg( NULL, "%s" S_COLOR_WHITE " gets an assist for returning the %s flag!\n", player->client->pers.netname, TeamName( team ) ); AddScore( player, CTF_RETURN_FLAG_ASSIST_BONUS ); other->client->pers.teamState.assists++; } if ( player->client->pers.teamState.lastfraggedcarrier + CTF_FRAG_CARRIER_ASSIST_TIMEOUT > level.time ) { PrintMsg( NULL, "%s" S_COLOR_WHITE " gets an assist for fragging the %s flag carrier!\n", player->client->pers.netname, TeamName( OtherTeam( team ) ) ); AddScore( player, CTF_FRAG_CARRIER_ASSIST_BONUS ); other->client->pers.teamState.assists++; } } } Team_ResetFlags(); CalculateRanks(); return 0; // Do not respawn this automatically }
void Team_ReturnFlag( int team ) { Team_ReturnFlagSound( Team_ResetFlag( team ), team ); PrintMsg( NULL, "The %s flag has returned!\n", TeamName( team ) ); }
/* ================ Team_FragBonuses Calculate the bonuses for flag defense, flag carrier defense, etc. Note that bonuses are not cumlative. You get one, they are in importance order. ================ */ void Team_FragBonuses( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker ) { int i; gentity_t *ent; int flag_pw, enemy_flag_pw; int otherteam; gentity_t *flag, *carrier = NULL; const char *c; vec3_t v1, v2; int team; // no bonus for fragging yourself if ( !targ->client || !attacker->client || targ == attacker ) { return; } team = targ->client->sess.sessionTeam; otherteam = OtherTeam( targ->client->sess.sessionTeam ); if ( otherteam < 0 ) { return; // whoever died isn't on a team } // same team, if the flag at base, check to he has the enemy flag if ( team == TEAM_RED ) { flag_pw = PW_REDFLAG; enemy_flag_pw = PW_BLUEFLAG; } else { flag_pw = PW_BLUEFLAG; enemy_flag_pw = PW_REDFLAG; } // did the attacker frag the flag carrier? if ( targ->client->ps.powerups[enemy_flag_pw] ) { attacker->client->pers.teamState.lastfraggedcarrier = level.time; AddScore( attacker, CTF_FRAG_CARRIER_BONUS ); attacker->client->pers.teamState.fragcarrier++; PrintMsg( NULL, "%s" S_COLOR_WHITE " fragged %s's flag carrier!\n", attacker->client->pers.netname, TeamName( team ) ); // the target had the flag, clear the hurt carrier // field on the other team for ( i = 0; i < g_maxclients.integer; i++ ) { ent = g_entities + i; if ( ent->inuse && ent->client->sess.sessionTeam == otherteam ) { ent->client->pers.teamState.lasthurtcarrier = 0; } } return; } if ( targ->client->pers.teamState.lasthurtcarrier && level.time - targ->client->pers.teamState.lasthurtcarrier < CTF_CARRIER_DANGER_PROTECT_TIMEOUT && !attacker->client->ps.powerups[flag_pw] ) { // attacker is on the same team as the flag carrier and // fragged a guy who hurt our flag carrier AddScore( attacker, CTF_CARRIER_DANGER_PROTECT_BONUS ); attacker->client->pers.teamState.carrierdefense++; team = attacker->client->sess.sessionTeam; PrintMsg( NULL, "%s" S_COLOR_WHITE " defends %s's flag carrier against an agressive enemy\n", attacker->client->pers.netname, TeamName( team ) ); return; } // flag and flag carrier area defense bonuses // we have to find the flag and carrier entities // find the flag switch ( attacker->client->sess.sessionTeam ) { case TEAM_RED: c = "team_CTF_redflag"; break; case TEAM_BLUE: c = "team_CTF_blueflag"; break; default: return; } flag = NULL; while ( ( flag = G_Find( flag, FOFS( classname ), c ) ) != NULL ) { if ( !( flag->flags & FL_DROPPED_ITEM ) ) { break; } } if ( !flag ) { return; // can't find attacker's flag } // find attacker's team's flag carrier for ( i = 0; i < g_maxclients.integer; i++ ) { carrier = g_entities + i; if ( carrier->inuse && carrier->client->ps.powerups[flag_pw] ) { break; } carrier = NULL; } // ok we have the attackers flag and a pointer to the carrier // check to see if we are defending the base's flag VectorSubtract( targ->s.origin, flag->s.origin, v1 ); VectorSubtract( attacker->s.origin, flag->s.origin, v2 ); if ( ( VectorLength( v1 ) < CTF_TARGET_PROTECT_RADIUS || VectorLength( v2 ) < CTF_TARGET_PROTECT_RADIUS || CanDamage( flag, targ->s.origin ) || CanDamage( flag, attacker->s.origin ) ) && attacker->client->sess.sessionTeam != targ->client->sess.sessionTeam ) { // we defended the base flag AddScore( attacker, CTF_FLAG_DEFENSE_BONUS ); attacker->client->pers.teamState.basedefense++; if ( !flag->r.contents ) { PrintMsg( NULL, "%s" S_COLOR_WHITE " defends the %s base.\n", attacker->client->pers.netname, TeamName( attacker->client->sess.sessionTeam ) ); } else { PrintMsg( NULL, "%s" S_COLOR_WHITE " defends the %s flag.\n", attacker->client->pers.netname, TeamName( attacker->client->sess.sessionTeam ) ); } return; } if ( carrier && carrier != attacker ) { VectorSubtract( targ->s.origin, carrier->s.origin, v1 ); VectorSubtract( attacker->s.origin, carrier->s.origin, v1 ); if ( VectorLength( v1 ) < CTF_ATTACKER_PROTECT_RADIUS || VectorLength( v2 ) < CTF_ATTACKER_PROTECT_RADIUS || CanDamage( carrier, targ->s.origin ) || CanDamage( carrier, attacker->s.origin ) ) { AddScore( attacker, CTF_CARRIER_PROTECT_BONUS ); attacker->client->pers.teamState.carrierdefense++; PrintMsg( NULL, "%s" S_COLOR_WHITE " defends the %s's flag carrier.\n", attacker->client->pers.netname, TeamName( attacker->client->sess.sessionTeam ) ); return; } } }
void BOTS_InfiltratorCommand_Disguise(int clientNum) { char firstCommand[MAX_TOKEN_CHARS]; char secondCommand[MAX_TOKEN_CHARS]; gentity_t *ent = g_entities + clientNum; infiltratorState_t *state = BOTS_Infiltrator_GetState(clientNum); int pLevel = ent->client->ps.persistant[PERS_LEVEL]; class_t cls = state->disguiseClass; team_t team = state->disguiseTeam; qboolean skinChanged = qfalse; char teamName[32]; char className[32]; if (trap_Argc() == 3) { memset(&firstCommand, 0, sizeof(firstCommand)); memset(&secondCommand, 0, sizeof(secondCommand)); trap_Argv( 1, firstCommand, sizeof( firstCommand ) ); trap_Argv( 2, secondCommand, sizeof( secondCommand ) ); team = BOTS_TeamNumber(firstCommand); if (team == TEAM_FREE) { BOTS_Print(clientNum, "invalid disguise team"); return; } else if (team == ent->bots_team && pLevel < 1) { BOTS_Print(clientNum, "must be level 1 to disguise as your team"); return; } else if (team != ent->bots_team && pLevel < 2) { BOTS_Print(clientNum, "must be level 2 to disguise as the enemy"); return; } cls = BOTS_ClassNumber(secondCommand); if (cls == CLASS_NONE) { BOTS_Print(clientNum, "invalid disguise class"); return; } } else if (trap_Argc() == 2) { memset(&firstCommand, 0, sizeof(firstCommand)); trap_Argv( 1, firstCommand, sizeof( firstCommand ) ); if (Q_stricmp(firstCommand, "clear") == 0) { cls = CLASS_NONE; team = TEAM_FREE; } else { BOTS_Print(clientNum, "invalid disguise"); return; } } if (cls == CLASS_NONE && team == TEAM_FREE) BOTS_Print(clientNum, "Disguised removed"); else { memset(&teamName, 0, 32); memcpy(&teamName, TeamName(team), 32); memset(&className, 0, 32); memcpy(&className, BOTS_ClassName(cls), 32); Q_strlwr(teamName); Q_strlwr(className); BOTS_Print(clientNum, va("Disguised as %s %s", teamName, className)); } BOTS_Infiltrator_ApplyDisguise(clientNum, team, cls); }
/* * Team_DroppedFlagThink */ int Team_TouchOurFlag(Gentity *ent, Gentity *other, int team) { int i; Gentity *player; Gclient *cl = other->client; int enemy_flag; if(g_gametype.integer == GT_1FCTF) enemy_flag = PW_NEUTRALFLAG; else{ if(cl->sess.team == TEAM_RED) enemy_flag = PW_BLUEFLAG; else enemy_flag = PW_REDFLAG; if(ent->flags & FL_DROPPED_ITEM){ /* hey, it's 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; } } /* 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 */ if(g_gametype.integer == GT_1FCTF) PrintMsg(NULL, "%s" S_COLOR_WHITE " captured the flag!\n", cl->pers.netname); else{ PrintMsg(NULL, "%s" S_COLOR_WHITE " captured the %s flag!\n", cl->pers.netname, TeamName(OtherTeam( team))); } 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.traj.base, other->client->sess.team, 1); Team_ForceGesture(other->client->sess.team); 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]; /* also make sure we don't award assist bonuses to the flag carrier himself. */ if(!player->inuse || player == other) continue; if(player->client->sess.team != cl->sess.team) player->client->pers.teamState.lasthurtcarrier = -5; else if(player->client->sess.team == cl->sess.team){ 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; } 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 */ }
qboolean dom_pickupflag (edict_t *ent, edict_t *other) { int i; edict_t *cl_ent; //if (!G_EntExists(other)) // return false; if (!other || !other->inuse || !other->client || G_IsSpectator(other)) return false; //if ((other->myskills.class_num == CLASS_POLTERGEIST) || other->mtype) // return false; // poltergeist and morphed players can't pick up flag // unmorph morphed players if (other->mtype) { other->mtype = 0; other->s.modelindex = 255; other->s.skinnum = ent-g_edicts-1; ShowGun(other); } // if this is a player-monster, remove the monster and restore the player if (PM_PlayerHasMonster(other)) PM_RemoveMonster(other); // disable movement abilities if (other->client) { //jetpack other->client->thrusting = 0; //grapple hook other->client->hook_state = HOOK_READY; } // super speed other->superspeed = false; // antigrav other->antigrav = false; VortexRemovePlayerSummonables(other); // disable scanner if (other->client->pers.scanner_active & 1) other->client->pers.scanner_active = 0; // reset their velocity VectorClear(other->velocity); // alert everyone gi.bprintf(PRINT_HIGH, "%s got the flag!\n", other->client->pers.netname); gi.bprintf(PRINT_HIGH, "The %s team is now in control.\n", TeamName(other)); // alert teammates for (i=0 ; i<game.maxclients ; i++) { cl_ent = g_edicts+1+i; if (G_EntExists(cl_ent) && (cl_ent->teamnum == other->teamnum) && (cl_ent != other)) gi.centerprintf(cl_ent, "Protect the flag carrier!\n"); } DEFENSE_TEAM = other->teamnum; // if a new team takes control of the flag, then reset the counter if (PREV_DEFENSE_TEAM != DEFENSE_TEAM) FLAG_FRAMES = 0; PREV_DEFENSE_TEAM = DEFENSE_TEAM; gi.sound(other, CHAN_ITEM, gi.soundindex("world/xianbeats.wav"), 1, ATTN_NORM, 0); other->client->pers.inventory[ITEM_INDEX(ent->item)] = 1; return true; }
/* ******************************************************************* * Function: int BehaviourFunction( const CKBehaviorContext& behaviorContext ) * * Description : The execution function is the function that will be called * during the process loop of the behavior engine, if the behavior * is defined as using an execution function. This function is not * called if the behavior is defined as a graph. This function is the * heart of the behavior: it should compute the essence of the behavior, * in an incremental way. The minimum amount of computing should be * done at each call, to leave time for the other behaviors to run. * The function receives the delay in milliseconds that has elapsed * since the last behavioral process, and should rely on this value to * manage the amount of effect it has on its computation, if the effect * of this computation relies on time. * * Parameters : * behaviourContext r Behavior context reference, which gives access to * frequently used global objects ( context, level, manager, etc... ) * * Returns : int, If it is done, it should return CKBR_OK. If it returns * CKBR_ACTIVATENEXTFRAME, the behavior will again be called * during the next process loop. * ******************************************************************* */ int GBLPFCreate::BehaviourFunction( const CKBehaviorContext& behaviorContext ) { CKBehavior *behaviour=behaviorContext.Behavior; CKContext *context = behaviorContext.Context; CGBLCOError returnValue(CGBLCOError::EGBLCOErrorType::GBLCO_OK); CKBOOL newTeam = true; CKERROR check; behaviour->ActivateInput(EGBLCreateBehInputs::In, false); //newTeam = behaviour->IsInputParameterEnabled(EGBLCreateParamInputs::Teamname); CGBLUserID NewPlayerId; CGBLTeamID TeamId; CGBLProfileManager *pm = (CGBLProfileManager *)context->GetManagerByGuid(GBLProfileManagerGUID); int buf; check = behaviour->GetInputParameterValue(EGBLCreateParamInputs::LAEID, &buf); if(check != CK_OK|| buf==0) { newTeam = false; } CGBLLAEID LAEID(buf); XString TeamName((CKSTRING)behaviour->GetInputParameterReadDataPtr(EGBLCreateParamInputs::Teamname)); CGBLProfileManager::EGBLUserType userType; behaviour->GetInputParameterValue(EGBLCreateParamInputs::Type, &userType); XString UserName((CKSTRING) behaviour->GetInputParameterReadDataPtr(EGBLCreateParamInputs::Username)); if(newTeam) { returnValue = pm->CreateTeamProfile(&TeamId, LAEID, TeamName); } else { returnValue = pm->CreatePlayerProfile(&NewPlayerId, userType, UserName); } if ((int)returnValue == CGBLCOError::EGBLCOErrorType::GBLCO_OK) { if (newTeam)//activate output with TeamId { behaviour->SetOutputParameterValue(EGBLCreateParamOutputs::ProfileId, &TeamId); } else //acitvate output with PlayerId { behaviour->SetOutputParameterValue(EGBLCreateParamOutputs::ProfileId, &NewPlayerId); } behaviour->ActivateOutput(EGBLCreateBehOutputs::Success, true); } else { CKParameterOut *pOut = behaviour->GetOutputParameter(EGBLCreateParamOutputs::ErrorCode); CGBLCOError::EGBLCOErrorType tType = CGBLCOError::EGBLCOErrorType::GBLCO_OK ; switch((CGBLCOError::EGBLCOErrorType)returnValue) { case 0: tType = CGBLCOError::EGBLCOErrorType::GBLCO_OK; break; case 1: tType = CGBLCOError::EGBLCOErrorType::GBLCO_FATAL; break; case 2: tType = CGBLCOError::EGBLCOErrorType::GBLCO_LOCAL; break; case 3: tType = CGBLCOError::EGBLCOErrorType::GBLCO_LOCAL; break; } const char*errorString = returnValue; TGBLError::SetTGBLError(pOut, tType,returnValue, (CKSTRING)errorString); //behaviour->SetOutputParameterValue(EGBLCreateParamOutputs::ErrorCode, &returnValue); behaviour->ActivateOutput(EGBLCreateBehOutputs::Error, true); } return CKBR_OK; }
void ThinkBalloonzone( gentity_t *self ) { //"(team == 0) ? TEAM_RED : TEAM_BLUE" => ! in this code red=0, blue=1 ! (unlike TEAM_RED(1), TEAM_BLUE(2) from team_t) // FIXME: Remove that offset team uglyness or at least make it readable!!1! int team, opponent; int numPlayers; team_t tteam; char *msg; if ( !self->message ) { msg = "Balloon"; } else { msg = self->message; } if ( self->target_ent->s.frame ) { // get teams team = ( self->target_ent->s.generic1 - 1 ); opponent = ( team ^ 1 ); tteam = ( team + 1 ); // capturing if ( ( self->target_ent->s.frame < 11 ) && ( self->teamMask & ( 1 << team ) ) && !( self->teamMask & (1 << opponent ) ) ) { numPlayers = NumPlayersAtBalloon( self, tteam ); if ( numPlayers <= 0 ) { numPlayers = 1; //... so, we must not check this later } self->teamTime[team] += ( BALLOON_THINKTIME * numPlayers ); self->target_ent->s.frame = ( 1 + self->teamTime[team] / ( 100 * self->speed ) ); if ( self->target_ent->s.frame >= 11 ) { // captured self->last_move_time = 0; self->teamTime[team] = 0; level.balloonState[self->count] = ( '1' + team ); trap_SetConfigstring( CS_BALLOONS, level.balloonState ); // TODO: Give more points for capturing than for owning? // Need to test balance! AddTeamScore( self->s.pos.trBase, tteam, ( BalloonScore() * 2 ), SCORE_BONUS_CAPTURE_S ); AddBalloonScores( self, tteam, 1 ); trap_SendServerCommand( -1, va( "mp \"%s captured by %s Team\"", msg, TeamName( tteam ) ) ); } } // balloon is fully raised if ( self->target_ent->s.frame >= 11 ) { // animate self->last_move_time += BALLOON_THINKTIME; if ( self->last_move_time >= ( 700 * self->speed ) ) { self->last_move_time -= ( 700 * self->speed ); } self->target_ent->s.frame = ( 11 + self->last_move_time / ( 100 * self->speed ) ); // give points if ( !level.intermissiontime ) { self->teamTime[team] += BALLOON_THINKTIME; while ( self->teamTime[team] >= BALLOON_POINTTIME ) { self->teamTime[team] -= BALLOON_POINTTIME; AddTeamScore( self->s.pos.trBase, tteam, ( BalloonScore() * 2 ), SCORE_BONUS_CAPTURE_TEAM_S ); } } } // countering capture if ( self->teamMask & (1 << opponent ) ) { numPlayers = NumPlayersAtBalloon( self, tteam ); if ( numPlayers <= 0 ) { numPlayers = 1; //... so, we must not check this later } if ( !self->teamTime[opponent] ) { self->teamTime[opponent] = level.time; } // FIXME: If some players come "later", they will also be calculated for the full time. else if ( level.time > ( self->teamTime[opponent] + ( self->wait * 1000 / numPlayers ) ) ) { // countered self->teamTime[0] = 0; self->teamTime[1] = 0; self->target_ent->s.frame = 0; level.balloonState[self->count] = '0'; trap_SetConfigstring( CS_BALLOONS, level.balloonState ); // TODO: Also give players//&team points for destroying a balloon? trap_SendServerCommand( -1, va( "mp \"%s destroyed by %s Team\"", msg, TeamName( OtherTeam( tteam ) ) ) ); } } else { self->teamTime[opponent] = 0; } } else { if ( ( self->teamMask & BT_RED ) && ( self->teamMask & BT_BLUE ) ) { // reset timer if both teams are trying to capture self->teamTime[0] = 0; self->teamTime[1] = 0; } else { for ( team = 0; team < 2; team++ ) { if ( self->teamMask & ( 1 << team ) ) { // start capture timer or test for capture if ( !self->teamTime[team] ) { self->teamTime[team] = level.time; } else if ( level.time > ( self->teamTime[team] + 1000 ) ) { self->teamTime[team] = 0; self->teamTime[team^1] = level.time; self->target_ent->s.generic1 = ( team + 1 ); self->target_ent->s.frame = 1; level.balloonState[self->count] = ( 'a' + team ); trap_SetConfigstring( CS_BALLOONS, level.balloonState ); trap_SendServerCommand( -1, va( "mp \"%s under attack by %s Team\"", msg, TeamName( team + 1 ) ) ); } } else { self->teamTime[team] = 0; } } } } // prepare next think //#@070329: some delay ... i think there isn't always a touch-call (with laging clients) // "TEAM_RED ? 0 : 1" @ teamTime[...] if ( ( self->target_ent->teamTime[0] + BALLOON_TOUCHDELAY ) < level.time ) { self->teamMask &= ~BT_RED; } if ( ( self->target_ent->teamTime[1] + BALLOON_TOUCHDELAY ) < level.time ) { self->teamMask &= ~BT_BLUE; } self->nextthink = ( level.time + BALLOON_THINKTIME ); }