for (int i = 1; i <= NUM_TEAMS; ++i)
{
Team_SetNumberOfAlivePlayers(Team_GetTeamFromIndex(i), 0);
+ Team_SetNumberOfPlayers(Team_GetTeamFromIndex(i), 0);
}
FOREACH_CLIENT(IS_PLAYER(it) && Entity_HasValidTeam(it),
{
++total_players;
+ entity team_ = Entity_GetTeam(it);
+
+ int num_total = Team_GetNumberOfPlayers(team_);
+ ++num_total;
+ Team_SetNumberOfPlayers(team_, num_total);
+
if (IS_DEAD(it))
{
continue;
}
- entity team_ = Entity_GetTeam(it);
+
int num_alive = Team_GetNumberOfAlivePlayers(team_);
++num_alive;
Team_SetNumberOfAlivePlayers(team_, num_alive);
}
int winner_team = CA_GetWinnerTeam();
+ bool perfect = false;
if(winner_team > 0)
{
entity last_pl = ca_LastPlayer(winner_team);
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN));
if(fragsleft > 1) Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, APP_TEAM_NUM(winner_team, ANNCE_ROUND_TEAM_WIN));
TeamScore_AddToTeam(winner_team, ST_CA_ROUNDS, +1);
+
+ entity tm = Team_GetTeam(winner_team);
+
+ if(Team_GetNumberOfAlivePlayers(tm) == Team_GetNumberOfPlayers(tm)) perfect = true;
}
else if(winner_team == -1)
{
game_stopped = true;
round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
- FOREACH_CLIENT(IS_PLAYER(it), { nades_Clear(it); });
+ FOREACH_CLIENT(IS_PLAYER(it), {
+ nades_Clear(it);
+
+ if(it.team == winner_team)
+ {
+ // Give perfect medal if everyone in the winner team is alive
+ if(perfect) {
+ Give_Medal(it, PERFECT);
+ }
+
+ // Give accuracy medal for each weapon above 50%
+ entity ra = it.roundaccuracy;
+ for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w) {
+ if(ra.accuracy_fired[w] && (ra.accuracy_hit[w] / ra.accuracy_fired[w]) > 0.5) {
+ Give_Medal(it, ACCURACY);
+ }
+ }
+ }
+ });
return 1;
}
MSG_ANNCE_NOTIF(ACHIEVEMENT_ELECTROBITCH, N__ALWAYS, "electrobitch", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
MSG_ANNCE_NOTIF(ACHIEVEMENT_IMPRESSIVE, N_GNTLOFF, "impressive", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
MSG_ANNCE_NOTIF(ACHIEVEMENT_YODA, N_GNTLOFF, "yoda", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_PERFECT, N_GNTLOFF, "perfect", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_ACCURACY, N_GNTLOFF, "accuracy", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
MSG_ANNCE_NOTIF(BEGIN, N__ALWAYS, "begin", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
MSG_MEDAL_NOTIF(IMPRESSIVE, N__ALWAYS, "impressive", ANNCE_ACHIEVEMENT_IMPRESSIVE)
MSG_MEDAL_NOTIF(YODA, N__ALWAYS, "yoda", ANNCE_ACHIEVEMENT_YODA)
+ MSG_MEDAL_NOTIF(PERFECT, N__ALWAYS, "perfect", ANNCE_ACHIEVEMENT_PERFECT)
+ MSG_MEDAL_NOTIF(ACCURACY, N__ALWAYS, "accuracy", ANNCE_ACHIEVEMENT_ACCURACY)
+
MSG_MEDAL_NOTIF(KILLSTREAK_03, N__ALWAYS, "killstreak_03", ANNCE_KILLSTREAK_03)
MSG_MEDAL_NOTIF(KILLSTREAK_05, N__ALWAYS, "killstreak_05", ANNCE_KILLSTREAK_05)
MSG_MEDAL_NOTIF(KILLSTREAK_10, N__ALWAYS, "killstreak_10", ANNCE_KILLSTREAK_10)
REGISTER_SP(ONS_CAPS);
REGISTER_SP(MEDAL_AIRSHOT);
-REGISTER_SP(MEDAL_ASSIST);
REGISTER_SP(MEDAL_DAMAGE);
-REGISTER_SP(MEDAL_DEFENSE);
REGISTER_SP(MEDAL_ELECTROBITCH);
REGISTER_SP(MEDAL_EXCELLENT);
REGISTER_SP(MEDAL_FIRSTBLOOD);
REGISTER_SP(MEDAL_IMPRESSIVE);
REGISTER_SP(MEDAL_YODA);
+REGISTER_SP(MEDAL_ACCURACY);
+REGISTER_SP(MEDAL_ASSIST);
+REGISTER_SP(MEDAL_DEFENSE);
+REGISTER_SP(MEDAL_PERFECT);
+
REGISTER_SP(MEDAL_KILLSTREAK_03);
REGISTER_SP(MEDAL_KILLSTREAK_05);
REGISTER_SP(MEDAL_KILLSTREAK_10);
this.cnt = 0;
this.round_endtime = (this.round_timelimit) ? time + this.round_timelimit : 0;
this.nextthink = time;
+ FOREACH_CLIENT(IS_PLAYER(it), { roundaccuracy_clear(it); });
if (this.roundStart) this.roundStart();
return;
}
team_ent.m_num_players_alive = number;
}
+int Team_GetNumberOfPlayers(entity team_ent)
+{
+ return team_ent.m_num_players;
+}
+
+void Team_SetNumberOfPlayers(entity team_ent, int number)
+{
+ team_ent.m_num_players = number;
+}
+
int Team_GetNumberOfAliveTeams()
{
int result = 0;
/// \param[in] team_ent Team entity.
/// \return Number of alive players in a team.
int Team_GetNumberOfAlivePlayers(entity team_ent);
+int Team_GetNumberOfPlayers(entity team_ent);
/// \brief Sets the number of alive players in a team.
/// \param[in,out] team_ent Team entity.
/// \param[in] number Number of players to set.
void Team_SetNumberOfAlivePlayers(entity team_ent, int number);
+void Team_SetNumberOfPlayers(entity team_ent, int number);
/// \brief Returns the number of alive teams.
/// \return Number of alive teams.
void accuracy_init(entity e)
{
entity a = CS(e).accuracy = new_pure(accuracy);
+ e.roundaccuracy = new_pure(accuracy);
a.owner = e;
if(!g_duel) // z411
a.drawonlytoclient = e;
void accuracy_free(entity e)
{
delete(CS(e).accuracy);
+ delete(e.roundaccuracy);
}
// force a resend of a player's accuracy stats
//.float hit_time;
.float fired_time;
+void roundaccuracy_clear(entity this)
+{
+ if (IS_INDEPENDENT_PLAYER(this)) return;
+ entity ra = this.roundaccuracy;
+
+ for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w) {
+ ra.accuracy_frags[w] = 0;
+ ra.accuracy_hit[w] = 0;
+ ra.accuracy_fired[w] = 0;
+ ra.accuracy_cnt_hit[w] = 0;
+ ra.accuracy_cnt_fired[w] = 0;
+ }
+}
+
void accuracy_add(entity this, Weapon w, int fired, int hit)
{
if (IS_INDEPENDENT_PLAYER(this)) return;
entity a = CS(this).accuracy;
+ entity ra = this.roundaccuracy;
if (!a) return;
if (!hit && !fired) return;
if (w == WEP_Null) return;
int wepid = w.m_id;
wepid -= WEP_FIRST;
int b = accuracy_byte(a.accuracy_hit[wepid], a.accuracy_fired[wepid]);
- if (hit) a.accuracy_hit [wepid] += hit;
- if (fired) a.accuracy_fired[wepid] += fired;
+ if (hit) {
+ a.accuracy_hit[wepid] += hit;
+ ra.accuracy_hit[wepid] += hit;
+ }
+ if (fired) {
+ a.accuracy_fired[wepid] += fired;
+ ra.accuracy_fired[wepid] += fired;
+ }
if (hit && STAT(HIT_TIME, a) != time) { // only run this once per frame
a.accuracy_cnt_hit[wepid] += 1;
+ ra.accuracy_cnt_hit[wepid] += 1;
STAT(HIT_TIME, a) = time;
}
if (fired && a.fired_time != time) { // only run this once per frame
a.accuracy_cnt_fired[wepid] += 1;
+ ra.accuracy_cnt_fired[wepid] += 1;
a.fired_time = time;
}
REPLICATE(cvar_cl_accuracy_data_receive, bool, "cl_accuracy_data_receive");
.entity accuracy;
+.entity roundaccuracy;
.float accuracy_frags[REGISTRY_MAX(Weapons)];
.float accuracy_hit[REGISTRY_MAX(Weapons)];
// update accuracy stats
void accuracy_add(entity e, Weapon w, float fired, float hit);
+void roundaccuracy_clear(entity this);
// helper
bool accuracy_isgooddamage(entity attacker, entity targ);