]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Added Perfect and Accuracy medals for Clan Arena
authorz411 <z411@omaera.org>
Tue, 20 Oct 2020 21:36:09 +0000 (18:36 -0300)
committerz411 <z411@omaera.org>
Tue, 20 Oct 2020 21:36:09 +0000 (18:36 -0300)
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc
qcsrc/common/notifications/all.inc
qcsrc/common/scores.qh
qcsrc/server/round_handler.qc
qcsrc/server/teamplay.qc
qcsrc/server/teamplay.qh
qcsrc/server/weapons/accuracy.qc
qcsrc/server/weapons/accuracy.qh

index 84e21534abeec17a2ae0ca9dddd86ad4e9ebfed8..0e03cae39c39f7b5e969a356c0071e60ff8e2a8d 100644 (file)
@@ -9,15 +9,22 @@ void CA_count_alive_players()
        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);
@@ -101,6 +108,7 @@ float CA_CheckWinner()
        }
 
        int winner_team = CA_GetWinnerTeam();
+       bool perfect = false;
        if(winner_team > 0)
        {
                entity last_pl = ca_LastPlayer(winner_team);
@@ -112,6 +120,10 @@ float CA_CheckWinner()
                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)
        {
@@ -125,7 +137,25 @@ float CA_CheckWinner()
                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;
 }
index b3255cf77f760d01c12ad46226cbea85190672c3..32f9fd0b7f64a97bf6749fb7db98772f18b9ce19 100644 (file)
     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)
index ee762ff249246d2e0f8f79697e0a6121b4e52749..b40378d18099864b9835be0da6d59ca4711f444f 100644 (file)
@@ -87,9 +87,7 @@ REGISTER_SP(ONS_TAKES);
 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);
@@ -98,6 +96,11 @@ REGISTER_SP(MEDAL_HUMILIATION);
 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);
index edd3942a2937e8afc60c16833041b0d348554931..ef64667473bad9dd487873dbeea576c2ff1e954a 100644 (file)
@@ -44,6 +44,7 @@ void round_handler_Think(entity this)
                                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;
                        }
index fbfacf9022ca02d3cf755bca2d51bb87d71f3c3f..6499d1f46bcc1b0ee5fd0f47289ce04897fc0ab7 100644 (file)
@@ -101,6 +101,16 @@ void Team_SetNumberOfAlivePlayers(entity team_ent, int number)
        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;
index 33f9d02d7e6b01da87c6dd86e6217b3ab546aa95..25fd2561a9e9e0b6987c159ce2a79fec8a44ec53 100644 (file)
@@ -39,11 +39,13 @@ void Team_SetTeamScore(entity team_ent, float score);
 /// \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.
index f430a7a3030ff701679fab326bf769846901bb43..5a6ebf6b7ad2a52c2304d8ece53be5ad0222fbd2 100644 (file)
@@ -61,6 +61,7 @@ bool accuracy_send(entity this, entity to, int sf)
 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;
@@ -70,6 +71,7 @@ void accuracy_init(entity e)
 void accuracy_free(entity e)
 {
        delete(CS(e).accuracy);
+       delete(e.roundaccuracy);
 }
 
 // force a resend of a player's accuracy stats
@@ -82,26 +84,49 @@ void accuracy_resend(entity e)
 //.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;
     }
 
index 396de1bdb36be71b066c106dac689d75e8bcb321..2bcaadbce7c0c4f2e71cb501a3215c935069526d 100644 (file)
@@ -9,6 +9,7 @@ REPLICATE(cvar_cl_accuracy_data_share, bool, "cl_accuracy_data_share");
 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)];
@@ -26,6 +27,7 @@ void accuracy_resend(entity e);
 
 // 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);