void Team_ReturnFlag( int team ) { Team_ReturnFlagSound(Team_ResetFlag(team), team); if( team == TEAM_FREE ) { //PrintMsg(NULL, "The flag has returned!\n" ); } else { //flag should always have team in normal CTF //PrintMsg(NULL, "The %s flag has returned!\n", TeamName(team)); PrintCTFMessage(-1, team, CTFMESSAGE_FLAG_RETURNED); } }
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 flag!\n", // other->client->pers.netname, TeamName(team)); PrintCTFMessage(other->s.number, team, CTFMESSAGE_PLAYER_GOT_FLAG); 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 }
int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) { gclient_t *cl = other->client; vec3_t mins, maxs; int num, j, ourFlag; int touch[MAX_GENTITIES]; gentity_t* enemy; float enemyDist, dist; VectorSubtract( ent->s.pos.trBase, minFlagRange, mins ); VectorAdd( ent->s.pos.trBase, maxFlagRange, maxs ); num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES ); dist = Distance(ent->s.pos.trBase, other->client->ps.origin); if (other->client->sess.sessionTeam == TEAM_RED){ ourFlag = PW_REDFLAG; } else { ourFlag = PW_BLUEFLAG; } for(j = 0; j < num; ++j){ enemy = (g_entities + touch[j]); if (!enemy || !enemy->inuse || !enemy->client){ continue; } //ignore specs if (enemy->client->sess.sessionTeam == TEAM_SPECTATOR) continue; //check if its alive if (enemy->health < 1) continue; // dead people can't pick up items //lets check if he has our flag if (!enemy->client->ps.powerups[ourFlag]) continue; //check if enemy is closer to our flag than us enemyDist = Distance(ent->s.pos.trBase,enemy->client->ps.origin); if (enemyDist < dist){ // possible recursion is hidden in this, but // infinite recursion wont happen, because we cant // have a < b and b < a at the same time return Team_TouchOurFlag( ent, enemy, team ); } } //PrintMsg (NULL, "%s" S_COLOR_WHITE " got the %s flag!\n", // other->client->pers.netname, TeamName(team)); PrintCTFMessage(other->s.number, team, CTFMESSAGE_PLAYER_GOT_FLAG); 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 }
int Team_TouchOurFlag( gentity_t *ent, gentity_t *other, int team ) { int i, num, j, enemyTeam; gentity_t *player; gclient_t *cl = other->client; int enemy_flag; vec3_t mins, maxs; int touch[MAX_GENTITIES]; gentity_t* enemy; float enemyDist, dist; 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)); PrintCTFMessage(other->s.number, team, CTFMESSAGE_PLAYER_RETURNED_FLAG); 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 // fix: captures after timelimit hit could // cause game ending with tied score if ( level.intermissionQueued ) { return 0; } // check for enemy closer to grab the flag VectorSubtract( ent->s.pos.trBase, minFlagRange, mins ); VectorAdd( ent->s.pos.trBase, maxFlagRange, maxs ); num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES ); dist = Distance(ent->s.pos.trBase, other->client->ps.origin); if (other->client->sess.sessionTeam == TEAM_RED){ enemyTeam = TEAM_BLUE; } else { enemyTeam = TEAM_RED; } for ( j=0 ; j<num ; j++ ) { enemy = (g_entities + touch[j]); if (!enemy || !enemy->inuse || !enemy->client){ continue; } //check if its alive if (enemy->health < 1) continue; // dead people can't pickup //ignore specs if (enemy->client->sess.sessionTeam == TEAM_SPECTATOR) continue; //check if this is enemy if ((enemy->client->sess.sessionTeam != TEAM_RED && enemy->client->sess.sessionTeam != TEAM_BLUE) || enemy->client->sess.sessionTeam != enemyTeam){ continue; } //check if enemy is closer to our flag than us enemyDist = Distance(ent->s.pos.trBase,enemy->client->ps.origin); if (enemyDist < dist){ // possible recursion is hidden in this, but // infinite recursion wont happen, because we cant // have a < b and b < a at the same time return Team_TouchEnemyFlag( ent, enemy, team ); } } //PrintMsg( NULL, "%s" S_COLOR_WHITE " captured the %s flag!\n", cl->pers.netname, TeamName(OtherTeam(team))); PrintCTFMessage(other->s.number, team, CTFMESSAGE_PLAYER_CAPTURED_FLAG); 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); //rww - don't really want to do this now. Mainly because performing a gesture disables your upper torso animations until it's done and you can't fire other->client->pers.teamState.captures++; 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 < sv_maxclients.integer; i++) { player = &g_entities[i]; 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); other->client->pers.teamState.assists++; player->client->ps.persistant[PERS_ASSIST_COUNT]++; player->client->rewardTime = level.time + REWARD_SPRITE_TIME; } //Raz: Was 'else if' meaning people were missing out on some assist scores 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]++; player->client->rewardTime = level.time + REWARD_SPRITE_TIME; } } } Team_ResetFlags(); CalculateRanks(); 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; int tokens; 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; } // 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)); PrintCTFMessage(attacker->s.number, team, CTFMESSAGE_FRAGGED_FLAG_CARRIER); // the target had the flag, clear the hurt carrier // field on the other team for (i = 0; i < sv_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 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 < sv_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); attacker->client->pers.teamState.carrierdefense++; targ->client->pers.teamState.lasthurtcarrier = 0; attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; team = attacker->client->sess.sessionTeam; 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]++; team = attacker->client->sess.sessionTeam; 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.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 < sv_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->pers.teamState.basedefense++; attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; 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 ( ( ( 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->pers.teamState.carrierdefense++; attacker->client->ps.persistant[PERS_DEFEND_COUNT]++; 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; 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)); PrintCTFMessage(other->s.number, team, CTFMESSAGE_PLAYER_RETURNED_FLAG); 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 //PrintMsg( NULL, "%s" S_COLOR_WHITE " captured the %s flag!\n", cl->pers.netname, TeamName(OtherTeam(team))); PrintCTFMessage(other->s.number, team, CTFMESSAGE_PLAYER_CAPTURED_FLAG); 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); //rww - don't really want to do this now. Mainly because performing a gesture disables your upper torso animations until it's done and you can't fire 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 }