]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
New medals
authorz411 <z411@omaera.org>
Sat, 3 Oct 2020 01:35:27 +0000 (22:35 -0300)
committerz411 <z411@omaera.org>
Sat, 3 Oct 2020 01:35:27 +0000 (22:35 -0300)
20 files changed:
qcsrc/client/hud/panel/centerprint.qc
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/client/main.qc
qcsrc/common/medals.qh [new file with mode: 0644]
qcsrc/common/medals/all.qh [new file with mode: 0644]
qcsrc/common/mutators/mutator/overkill/oknex.qc
qcsrc/common/notifications/all.inc
qcsrc/common/notifications/all.qc
qcsrc/common/notifications/all.qh
qcsrc/common/scores.qh
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/electro.qc
qcsrc/common/weapons/weapon/mortar.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/common/weapons/weapon/vortex.qc
qcsrc/server/client.qh
qcsrc/server/damage.qc
qcsrc/server/damage.qh
qcsrc/server/scores.qc
qcsrc/server/weapons/tracing.qc

index 88819c932e605cbe9396a959e16fa24305b8dfe9..2948a0decbb37ee132f13e6962ef17a611458179 100644 (file)
@@ -45,7 +45,7 @@ bool centerprint_showing;
 
 float centerprint_medal_expire_time;
 string centerprint_medal_icon;
-int centerprint_medal_times;
+float centerprint_medal_times;
 
 bool centerprint_title_show;
 string centerprint_title;
@@ -65,7 +65,7 @@ void centerprint_SetTitle(string title)
        }
 }
 
-void centerprint_Medal(string icon, int times)
+void centerprint_Medal(string icon, float times)
 {
        LOG_INFOF("centerprint_Medal: icon: %s times: %d", icon, times);
        
@@ -274,19 +274,32 @@ void HUD_CenterPrint()
        pos.y -= height;
        
        // z411 draw medals first
-       if (centerprint_medal_expire_time > time) {
-               //if(centerprint_medal_expire_time - time > 1)
-               //      a = 1;
-               //else
-               //      a = min(1, 1 - ((centerprint_medal_expire_time - time + 2) * (1/3)));
+       if (time < centerprint_medal_expire_time) {
+               if(time < centerprint_medal_expire_time - 1)
+                       a = 1;
+               else
+                       a = centerprint_medal_expire_time - time;
+               
+               vector tmp_in = pos;
                        
                mysize = draw_getimagesize(centerprint_medal_icon);
                newsize = vec2(height*(mysize.x/mysize.y), height);
+               fontsize = '1 1 0' * (newsize.y/2);
                
-               //fontsize = '1 1 0' * vid_conheight/50 * autocvar_hud_panel_centerprint_fontscale;
-               //drawcolorcodedstring(pos + eY * 0.5 * (1 - sz * hud_scale.x) * fontsize.y, ts, fontsize, 1, DRAWFLAG_NORMAL);
-               //drawstring(pos, centerprint_medal_icon, fontsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-               drawpic(pos + eX * 0.5 * panel_size.x - eX * (newsize.x / 2), centerprint_medal_icon, newsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+               tmp_in.x += (panel_size.x - newsize.x) / 2; // center medal icon
+               
+               if(centerprint_medal_times <= 5) {
+                       tmp_in.x -= ((newsize.x * 1.1) * (centerprint_medal_times - 1) / 2);
+                       for(int t = 0; t < centerprint_medal_times; t++) {
+                               drawpic(tmp_in, centerprint_medal_icon, newsize, '1 1 1', a, DRAWFLAG_NORMAL);
+                               tmp_in.x += newsize.x * 1.1;
+                       }
+               } else {
+                       drawpic(tmp_in, centerprint_medal_icon, newsize, '1 1 1', a, DRAWFLAG_NORMAL);
+                       tmp_in.x += newsize.x + fontsize.x * 0.25; // draw times next to it
+                       tmp_in.y += (newsize.y - fontsize.y) / 2;
+                       drawstring(tmp_in, ftos(centerprint_medal_times), fontsize, '1 1 1', a, DRAWFLAG_NORMAL);
+               }
                
                all_messages_expired = false;
        }
index 0cea8df91d3da6a8658b16f1b0467b7da7951e20..0fcb5c5608ec68e370278364818bd3b5053e8bda 100644 (file)
@@ -49,6 +49,7 @@ float max_namesize;
 vector duel_score_fontsize;
 vector duel_name_fontsize;
 vector duel_score_size;
+int total_medals;
 
 float sbt_bg_alpha;
 float sbt_fg_alpha;
@@ -1055,6 +1056,25 @@ vector Scoreboard_DrawOthers(vector item_pos, vector rgb, int this_team, entity
        return vec2(item_pos.x, item_pos.y + i * hud_fontsize.y * 1.25);
 }
 
+vector Scoreboard_DrawMedal(vector pos, string icon, float height, float number)
+{
+       if(!number) return pos;
+       total_medals += number;
+       
+       vector tmp_sz, tmp_sz2;
+       tmp_sz = draw_getimagesize(icon);
+       tmp_sz2 = vec2(height*(tmp_sz.x/tmp_sz.y), height);
+       string val = ftos(number);
+       
+       drawpic(pos, icon, tmp_sz2, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       pos.x += tmp_sz2.x + hud_fontsize.x * 0.25;
+       drawstring(pos + eY * ((tmp_sz2.y - hud_fontsize.y) / 2), val, hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       pos.x += stringwidth(val, false, hud_fontsize) + hud_fontsize.x * 0.5;
+       return pos;
+}
+
 vector Scoreboard_Duel_DrawPickup(vector pos, bool skinned, string icon, vector sz, float number, bool invert)
 {
        vector tmp_in = pos;
@@ -1082,7 +1102,7 @@ vector Scoreboard_Duel_DrawPickup(vector pos, bool skinned, string icon, vector
        else
                tmp_in.x -= hud_fontsize.x * 0.25 + hud_fontsize.x;
        tmp_in.y += (tmp_sz2.y - hud_fontsize.y) / 2;
-       drawstring(tmp_in, ftos(number), hud_fontsize, '0.5 0.5 0.5', panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawstring(tmp_in, ftos(number), hud_fontsize, (number ? '1 1 1' : '0.5 0.5 0.5'), panel_fg_alpha, DRAWFLAG_NORMAL);
        
        pos.y += sz.y * 1.1;
        return pos;
@@ -1211,19 +1231,19 @@ void Scoreboard_Duel_DrawTable(vector pos, bool invert, entity pl, entity tm)
                
                draw_str = ftos(pl.accuracy_frags[i - WEP_FIRST]);
                drawstring(tmp_in + eX * column_width * (invert ? c-- : c++) + eX * ((column_width - stringwidth(draw_str, false, hud_fontsize)) / 2),
-                       draw_str, hud_fontsize, '0.5 0.5 0.5', panel_fg_alpha, DRAWFLAG_NORMAL);
+                       draw_str, hud_fontsize, (weapon_cnt_fired ? '1 1 1' : '0.5 0.5 0.5'), panel_fg_alpha, DRAWFLAG_NORMAL);
                
                draw_str = ftos(pl.accuracy_hit[i - WEP_FIRST]);
                drawstring(tmp_in + eX * column_width * (invert ? c-- : c++) + eX * ((column_width - stringwidth(draw_str, false, hud_fontsize)) / 2),
-                       draw_str, hud_fontsize, '0.5 0.5 0.5', panel_fg_alpha, DRAWFLAG_NORMAL);
+                       draw_str, hud_fontsize, (weapon_cnt_fired ? '1 1 1' : '0.5 0.5 0.5'), panel_fg_alpha, DRAWFLAG_NORMAL);
                        
                draw_str = sprintf("%d%%", weapon_acc);
                drawstring(tmp_in + eX * column_width * (invert ? c-- : c++) + eX * ((column_width - stringwidth(draw_str, false, hud_fontsize)) / 2),
-                       draw_str, hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+                       draw_str, hud_fontsize, (weapon_cnt_fired ? '1 1 1' : '0.5 0.5 0.5'), panel_fg_alpha, DRAWFLAG_NORMAL);
                        
                draw_str = strcat(ftos(weapon_cnt_hit), " / ", ftos(weapon_cnt_fired));
                drawstring(tmp_in + eX * column_width * (invert ? c-- : c++) + eX * (column_width / 2) - eX * stringwidth("36 /", false, hud_fontsize),
-                       draw_str,hud_fontsize, '0.5 0.5 0.5', panel_fg_alpha, DRAWFLAG_NORMAL);
+                       draw_str,hud_fontsize, (weapon_cnt_fired ? '1 1 1' : '0.5 0.5 0.5'), panel_fg_alpha, DRAWFLAG_NORMAL);
        
                // weapon icon
                if(invert) {
@@ -1254,9 +1274,9 @@ void Scoreboard_Duel_DrawTable(vector pos, bool invert, entity pl, entity tm)
                "medals", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
        tmp.y += hud_fontsize.y * 1.25;
        
-       tmp = Scoreboard_Duel_DrawPickup(tmp, false, "gfx/medal/yoda", icon_sz, 0, invert);
-       tmp = Scoreboard_Duel_DrawPickup(tmp, false, "gfx/medal/airshot", icon_sz, 0, invert);
-       tmp = Scoreboard_Duel_DrawPickup(tmp, false, "gfx/medal/firstblood", icon_sz, 0, invert);
+       tmp = Scoreboard_Duel_DrawPickup(tmp, false, "gfx/medal/humiliation", icon_sz, pl.(scores(SP_MEDAL_HUMILIATION)), invert);
+       tmp = Scoreboard_Duel_DrawPickup(tmp, false, "gfx/medal/impressive", icon_sz, pl.(scores(SP_MEDAL_IMPRESSIVE)), invert);
+       tmp = Scoreboard_Duel_DrawPickup(tmp, false, "gfx/medal/excellent", icon_sz, pl.(scores(SP_MEDAL_EXCELLENT)), invert);
        
        // Item rows
        drawstring(tmp + eX * ((column_width - stringwidth("items", false, hud_fontsize)) / 2),
@@ -1279,29 +1299,8 @@ vector Scoreboard_MakeDuelTable(vector pos, entity tm, vector rgb, vector bg_siz
        float screen_half = panel_size.x / 2;
        float weapon_margin = hud_fontsize.x;
        
-       // Get weapon count
-       WepSet weapons_inmap = WepSet_GetFromStat_InMap();
-       int disownedcnt = 0;
-       int nHidden = 0;
-       FOREACH(Weapons, it != WEP_Null, {
-               WepSet set = it.m_wepset;
-               if(it.spawnflags & WEP_TYPE_OTHER)
-               {
-                       ++nHidden;
-                       continue;
-               }
-               if (!(weapons_inmap & set))
-               {
-                       if (it.spawnflags & (WEP_FLAG_HIDDEN | WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_SPECIALATTACK))
-                               ++nHidden;
-                       else
-                               ++disownedcnt;
-               }
-       });
-
-       int weapon_cnt = (REGISTRY_COUNT(Weapons) - 1) - disownedcnt - nHidden;
        panel_size.x = screen_half - weapon_margin;
-       panel_size.y = (duel_score_size.y * 3) + (hud_fontsize.y * 1.25 * weapon_cnt);
+       panel_size.y = (duel_score_size.y * 5.5);
        
        entity pl_left = players.sort_next;
        entity pl_right = pl_left.sort_next;
@@ -1429,6 +1428,41 @@ bool Scoreboard_WouldDraw()
        return false;
 }
 
+vector Scoreboard_MedalStats_Draw(vector pos)
+{
+       vector orig = pos;
+       float height = hud_fontsize.y * 2;
+       
+       entity pl = playerslots[current_player];
+       
+       vector title_pos = pos;
+       pos.x += 0.5 * hud_fontsize.x + panel_bg_padding;
+       pos.y += 1.25 * hud_fontsize.y;
+       
+       total_medals = 0;
+       
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/airshot",            height, pl.(scores(SP_MEDAL_AIRSHOT)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/assist",             height, pl.(scores(SP_MEDAL_ASSIST)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/damage",             height, pl.(scores(SP_MEDAL_DAMAGE)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/defense",            height, pl.(scores(SP_MEDAL_DEFENSE)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/electrobitch",       height, pl.(scores(SP_MEDAL_ELECTROBITCH)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/excellent",          height, pl.(scores(SP_MEDAL_EXCELLENT)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/firstblood",         height, pl.(scores(SP_MEDAL_FIRSTBLOOD)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/headshot",           height, pl.(scores(SP_MEDAL_HEADSHOT)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/humiliation",        height, pl.(scores(SP_MEDAL_HUMILIATION)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/impressive",         height, pl.(scores(SP_MEDAL_IMPRESSIVE)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/yoda",                       height, pl.(scores(SP_MEDAL_YODA)));
+       
+       if(!total_medals) return orig;
+       
+       drawstring(title_pos, sprintf(_("Medal stats (total %d)"), total_medals),
+               hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       pos.x = orig.x;
+       pos.y += height + hud_fontsize.y * 0.5;
+       return pos;
+}
+
 float average_accuracy;
 vector Scoreboard_AccuracyStats_Draw(vector pos, vector rgb, vector bg_size)
 {
@@ -2114,6 +2148,8 @@ void Scoreboard_Draw()
                pos = Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size);
        }
 
+       pos = Scoreboard_MedalStats_Draw(pos);
+       
        if (Scoreboard_AccuracyStats_WouldDraw(pos.y))
                pos = Scoreboard_AccuracyStats_Draw(pos, panel_bg_color, bg_size);
 
index fdd3a34eb028b5e873d1ee698b3c2af0a290e530..dd01090f334d31367c122290311b7b052b5ec720 100644 (file)
@@ -622,7 +622,7 @@ NET_HANDLE(ENT_CLIENT_ACCURACY, bool isnew)
                                playerslots[entnum-1].accuracy_cnt_hit[w] = ReadShort();
                                playerslots[entnum-1].accuracy_cnt_fired[w] = ReadShort();
                                
-                               LOG_INFOF("Duel stats ?/%d", playerslots[entnum-1].accuracy_cnt_fired[w]);
+                               //LOG_INFOF("Duel stats ?/%d", playerslots[entnum-1].accuracy_cnt_fired[w]);
                        } else {
                                int b = ReadByte();
                                if (b == 0)
diff --git a/qcsrc/common/medals.qh b/qcsrc/common/medals.qh
new file mode 100644 (file)
index 0000000..b12581b
--- /dev/null
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <common/command/_mod.qh>
+
+#include <common/notifications/all.qh>
+
+REGISTRY(Medals, 32)
+REGISTER_REGISTRY(Medals)
+#define REGISTER_MEDAL(id, class) REGISTER(Medals, MEDAL, id, m_id, NEW(class))
+
+REGISTRY_SORT(Medals)
+REGISTRY_CHECK(Medals)
+
+REGISTRY_DEFINE_GET(Medals, NULL)
+STATIC_INIT(Medals) { FOREACH(Medals, true, it.m_id = i); }
+
+CLASS(Medal, Object)
+ENDCLASS(Medal)
+
+REGISTER_MEDAL(Airshot, Medal) {
+    this.netname                =   "airshot";
+    this.m_name                 =   _("Airshot");
+    this.m_icon                 =   "airshot";
+       this.m_annce                                    =   ANNCE_ACHIEVEMENT_IMPRESSIVE;
+}
+
+REGISTER_MEDAL(Impressive, Medal) {
+    this.netname                =   "impressive";
+    this.m_name                 =   _("Impressive");
+    this.m_icon                 =   "impressive";
+       //this.m_annce                                  =   ANNCE_ACHIEVEMENT_IMPRESSIVE;
+}
+
diff --git a/qcsrc/common/medals/all.qh b/qcsrc/common/medals/all.qh
new file mode 100644 (file)
index 0000000..bfbc610
--- /dev/null
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <common/command/_mod.qh>
+
+#include "medal.qh"
+
+// NOTE: 24 is the limit for the .items field
+REGISTRY(Medals, 32)
+REGISTER_REGISTRY(Medals)
+#define REGISTER_MEDAL(id, class) REGISTER(Medals, MEDAL, id, m_id, NEW(class))
+
+REGISTRY_SORT(Medals)
+REGISTRY_CHECK(Medals)
+
+REGISTRY_DEFINE_GET(Medals, NULL)
+STATIC_INIT(Medals) { FOREACH(Medals, true, it.m_id = i); }
+
+CLASS(Medal)
+ENDCLASS(Medal)
+
+REGISTER_ITEM(Impressive, Medal) {
+#ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE;
+    this.m_model                =   MDL_HealthSmall_ITEM;
+    this.m_sound                =   SND_HealthSmall;
+#endif
+    this.netname                =   "impressive";
+    this.m_name                 =   _("Impressive");
+    this.m_icon                 =   "impressive";
+#ifdef SVQC
+       this.annce                                      =   ANNCE_ACHIEVEMENT_IMPRESSIVE;
+#endif
+}
index e5e0b7e845f1ffaf7476e02731de4d3df3a32bee..bba6db11d4b157e940c62a2ad09fb478ecde7bda 100644 (file)
@@ -97,12 +97,13 @@ void W_OverkillNex_Attack(Weapon thiswep, entity actor, .entity weaponentity, fl
        damage_goodhits = 0;
        FireRailgunBullet(actor, weaponentity, w_shotorg, w_shotorg + w_shotdir * max_shot_distance, mydmg, true, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, thiswep.m_id);
 
-       if(yoda && flying)
-               Send_Notification(NOTIF_ONE, actor, MSG_MEDAL, MEDAL_YODA);
+       if(yoda && flying) {
+               Give_Medal(actor, YODA);
+       }
+               
        if(damage_goodhits && actor.oknex_lasthit)
        {
-               //Send_Notification(NOTIF_ONE, actor, MSG_ANNCE, ANNCE_ACHIEVEMENT_IMPRESSIVE);
-               Send_Notification(NOTIF_ONE, actor, MSG_MEDAL, MEDAL_IMPRESSIVE);
+               Give_Medal(actor, IMPRESSIVE);
                damage_goodhits = 0; // only every second time
        }
 
index 930c6d21b17d388439fcc21780ef04ed9d9098fc..f421867f831d2ecaf9474313bb96e71c52fe378f 100644 (file)
 // MSG_ANNCE_NOTIFICATIONS
     MSG_ANNCE_NOTIF(ACHIEVEMENT_AIRSHOT,        N_GNTLOFF, "airshot",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
     MSG_ANNCE_NOTIF(ACHIEVEMENT_AMAZING,        N_GNTLOFF, "amazing",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-    MSG_ANNCE_NOTIF(ACHIEVEMENT_AWESOME,        N_GNTLOFF, "awesome",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
+       MSG_ANNCE_NOTIF(ACHIEVEMENT_ASSIST,         N_GNTLOFF, "assist",            CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
+       MSG_ANNCE_NOTIF(ACHIEVEMENT_AWESOME,        N_GNTLOFF, "awesome",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
+       MSG_ANNCE_NOTIF(ACHIEVEMENT_DAMAGE,         N_GNTLOFF, "damage",            CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
+       MSG_ANNCE_NOTIF(ACHIEVEMENT_DEFENSE,        N_GNTLOFF, "defense",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
+       MSG_ANNCE_NOTIF(ACHIEVEMENT_EXCELLENT,      N_GNTLOFF, "excellent",         CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
     MSG_ANNCE_NOTIF(ACHIEVEMENT_BOTLIKE,        N_GNTLOFF, "botlike",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
     MSG_ANNCE_NOTIF(ACHIEVEMENT_ELECTROBITCH,   N__ALWAYS, "electrobitch",      CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
     MSG_ANNCE_NOTIF(ACHIEVEMENT_IMPRESSIVE,     N_GNTLOFF, "impressive",        CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
     MSG_ANNCE_NOTIF(BEGIN,                      N__ALWAYS, "begin",             CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
 
     MSG_ANNCE_NOTIF(HEADSHOT,                   N__ALWAYS, "headshot",          CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
+       MSG_ANNCE_NOTIF(HUMILIATION,                N__ALWAYS, "humiliation",       CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
 
     MSG_ANNCE_NOTIF(KILLSTREAK_03,              N_GNTLOFF, "03kills",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
     MSG_ANNCE_NOTIF(KILLSTREAK_05,              N_GNTLOFF, "05kills",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
     MSG_ANNCE_NOTIF(KILLSTREAK_10,              N_GNTLOFF, "10kills",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
     MSG_ANNCE_NOTIF(KILLSTREAK_15,              N_GNTLOFF, "15kills",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-    MSG_ANNCE_NOTIF(KILLSTREAK_20,              N_GNTLOFF, "20kills",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-    MSG_ANNCE_NOTIF(KILLSTREAK_25,              N_GNTLOFF, "25kills",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-    MSG_ANNCE_NOTIF(KILLSTREAK_30,              N_GNTLOFF, "30kills",           CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
 
     MSG_ANNCE_NOTIF(INSTAGIB_LASTSECOND,        N_GNTLOFF, "lastsecond",        CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
     MSG_ANNCE_NOTIF(INSTAGIB_NARROWLY,          N_GNTLOFF, "narrowly",          CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
        MSG_ANNCE_NOTIF(ALONE,                      N__ALWAYS, "alone",             CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
 
 // MSG_MEDAL_NOTIFICATIONS
-       MSG_MEDAL_NOTIF(AIRSHOT, N__ALWAYS,    "airshot",  ANNCE_ACHIEVEMENT_AIRSHOT)
-       MSG_MEDAL_NOTIF(HEADSHOT, N__ALWAYS,   "headshot", ANNCE_HEADSHOT)
-       MSG_MEDAL_NOTIF(IMPRESSIVE, N__ALWAYS, "impressive", ANNCE_ACHIEVEMENT_IMPRESSIVE)
-       MSG_MEDAL_NOTIF(YODA, N__ALWAYS, "yoda", ANNCE_ACHIEVEMENT_YODA)
+       MSG_MEDAL_NOTIF(AIRSHOT, N__ALWAYS,        "airshot",       ANNCE_ACHIEVEMENT_AIRSHOT)
+       MSG_MEDAL_NOTIF(ASSIST, N__ALWAYS,         "assist",        ANNCE_ACHIEVEMENT_ASSIST)
+       MSG_MEDAL_NOTIF(DAMAGE, N__ALWAYS,         "damage",        ANNCE_ACHIEVEMENT_DAMAGE)
+       MSG_MEDAL_NOTIF(DEFENSE, N__ALWAYS,        "defense",       ANNCE_ACHIEVEMENT_DEFENSE)
+       MSG_MEDAL_NOTIF(ELECTROBITCH, N__ALWAYS,   "electrobitch",  ANNCE_ACHIEVEMENT_ELECTROBITCH)
+       MSG_MEDAL_NOTIF(EXCELLENT, N__ALWAYS,      "excellent",     ANNCE_ACHIEVEMENT_EXCELLENT)
+       MSG_MEDAL_NOTIF(FIRSTBLOOD, N__ALWAYS,     "firstblood",    ANNCE_FIRSTBLOOD)
+       MSG_MEDAL_NOTIF(HEADSHOT, N__ALWAYS,       "headshot",      ANNCE_HEADSHOT)
+       MSG_MEDAL_NOTIF(HUMILIATION, N__ALWAYS,    "humiliation",   ANNCE_HUMILIATION)
+       MSG_MEDAL_NOTIF(IMPRESSIVE, N__ALWAYS,     "impressive",    ANNCE_ACHIEVEMENT_IMPRESSIVE)
+       MSG_MEDAL_NOTIF(YODA, N__ALWAYS,           "yoda",          ANNCE_ACHIEVEMENT_YODA)
        
        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)
        MSG_MEDAL_NOTIF(KILLSTREAK_15, N__ALWAYS, "killstreak_15", ANNCE_KILLSTREAK_15)
-       MSG_MEDAL_NOTIF(KILLSTREAK_20, N__ALWAYS, "killstreak_20", ANNCE_KILLSTREAK_20)
-       MSG_MEDAL_NOTIF(KILLSTREAK_25, N__ALWAYS, "killstreak_25", ANNCE_KILLSTREAK_25)
-       MSG_MEDAL_NOTIF(KILLSTREAK_30, N__ALWAYS, "killstreak_30", ANNCE_KILLSTREAK_30)
-       
-       MSG_MEDAL_NOTIF(FIRSTBLOOD, N__ALWAYS, "firstblood", ANNCE_FIRSTBLOOD)
        
 
 #undef N___NEVER
index 503c67c03d917e8570cab1d82444ebb79f3b5410..972b0d0920225cc3bab0e454a20de58c0c90a0b3 100644 (file)
@@ -759,6 +759,7 @@ void Create_Notification_Entity_Medal(entity notif,
                                                                                string icon,
                                                                                Notification anncename)
        {
+               notif.nent_floatcount = 1;
                if (icon != "") { notif.nent_icon = strzone(icon); }
                if (anncename) { notif.nent_msgannce = anncename; }
        }
@@ -1199,7 +1200,7 @@ void Local_Notification_centerprint_Add(
        centerprint_Add(ORDINAL(cpid), input, stof(arg_slot[0]), stof(arg_slot[1]));
 }
 
-void Local_Notification_Queue_Run(MSG net_type, entity notif)
+void Local_Notification_Queue_Run(MSG net_type, entity notif, float f1)
 {              
        switch (net_type)
        {
@@ -1211,14 +1212,14 @@ void Local_Notification_Queue_Run(MSG net_type, entity notif)
                
                case MSG_MEDAL:
                {
-                       centerprint_Medal(notif.nent_icon, 1);
+                       centerprint_Medal(notif.nent_icon, f1);
                        Local_Notification_sound(notif.nent_msgannce.nent_channel, notif.nent_msgannce.nent_snd, notif.nent_msgannce.nent_vol, notif.nent_msgannce.nent_position);
                        break;
                }
        }
 }
 
-void Local_Notification_Queue_Add(MSG net_type, entity notif, float queue_time)
+void Local_Notification_Queue_Add(MSG net_type, entity notif, float queue_time, float f1)
 {      
        if(notif_queue_length >= NOTIF_QUEUE_MAX)
                return;
@@ -1227,13 +1228,14 @@ void Local_Notification_Queue_Add(MSG net_type, entity notif, float queue_time)
        
        if(time > notif_queue_next_time) {
                //LOG_INFOF("Running NOW!");
-               Local_Notification_Queue_Run(net_type, notif);
+               Local_Notification_Queue_Run(net_type, notif, f1);
                notif_queue_next_time = time + queue_time;
        } else {
                //LOG_INFOF("Queueing: %d %d", notif_queue_length, notif_queue_next_time);
                notif_queue_type[notif_queue_length] = net_type;
                notif_queue_entity[notif_queue_length] = notif;
                notif_queue_time[notif_queue_length] = notif_queue_next_time;
+               notif_queue_f1[notif_queue_length] = f1;
                
                notif_queue_next_time += queue_time;
                ++notif_queue_length;
@@ -1249,13 +1251,14 @@ void Local_Notification_Queue_Process()
        
        if(notif_queue_time[0] <= time) {
                //LOG_INFOF("Process running: %d <= %d", notif_queue_time[0], time);
-               Local_Notification_Queue_Run(notif_queue_type[0], notif_queue_entity[0]);
+               Local_Notification_Queue_Run(notif_queue_type[0], notif_queue_entity[0], notif_queue_f1[0]);
                
                // Shift queue to the left
                for (j = 0; j < notif_queue_length - 1; j++) { 
                        notif_queue_type[j] = notif_queue_type[j+1];
                        notif_queue_entity[j] = notif_queue_entity[j+1];
                        notif_queue_time[j] = notif_queue_time[j+1];
+                       notif_queue_f1[j] = notif_queue_f1[j+1];
                } 
                
                --notif_queue_length;
@@ -1335,7 +1338,11 @@ void Local_Notification(MSG net_type, Notification net_name, ...count)
                {
                        #ifdef CSQC
                        //Local_Notification_sound(notif.nent_channel, notif.nent_snd, notif.nent_vol, notif.nent_position);
-                       Local_Notification_Queue_Add(net_type, notif, 1);
+                       Local_Notification_Queue_Add(
+                               net_type,
+                               notif,
+                               1,
+                               f1);
                        #else
                        backtrace("MSG_ANNCE on server?... Please notify Samual immediately!\n");
                        #endif
@@ -1449,7 +1456,11 @@ void Local_Notification(MSG net_type, Notification net_name, ...count)
                #ifdef CSQC
                case MSG_MEDAL:
                {
-                       Local_Notification_Queue_Add(net_type, notif, 3);
+                       Local_Notification_Queue_Add(
+                               net_type,
+                               notif,
+                               3,
+                               f1);
                        break;
                }
                #endif
index 2b39c17ba30a44742d50139d7555127eeafdcee4..af4b0dc44a1273750c4c6c62f0a328adfc878b0d 100644 (file)
@@ -402,6 +402,8 @@ const int NOTIF_QUEUE_MAX = 10;
 entity notif_queue_entity[NOTIF_QUEUE_MAX];
 MSG notif_queue_type[NOTIF_QUEUE_MAX];
 float notif_queue_time[NOTIF_QUEUE_MAX];
+float notif_queue_f1[NOTIF_QUEUE_MAX];
+
 float notif_queue_next_time;
 int notif_queue_length;
 
@@ -478,9 +480,6 @@ MACRO_END
        SPREE_ITEM(5, 05, _("RAGE! "), _("%s^K1 unlocked RAGE! %s^BG"), _("%s^K1 made FIVE SCORES IN A ROW! %s^BG")) \
        SPREE_ITEM(10, 10, _("MASSACRE! "), _("%s^K1 started a MASSACRE! %s^BG"), _("%s^K1 made TEN SCORES IN A ROW! %s^BG")) \
        SPREE_ITEM(15, 15, _("MAYHEM! "), _("%s^K1 executed MAYHEM! %s^BG"), _("%s^K1 made FIFTEEN SCORES IN A ROW! %s^BG")) \
-       SPREE_ITEM(20, 20, _("BERSERKER! "), _("%s^K1 is a BERSERKER! %s^BG"), _("%s^K1 made TWENTY SCORES IN A ROW! %s^BG")) \
-       SPREE_ITEM(25, 25, _("CARNAGE! "), _("%s^K1 inflicts CARNAGE! %s^BG"), _("%s^K1 made TWENTY FIVE SCORES IN A ROW! %s^BG")) \
-       SPREE_ITEM(30, 30, _("ARMAGEDDON! "), _("%s^K1 unleashes ARMAGEDDON! %s^BG"), _("%s^K1 made THIRTY SCORES IN A ROW! %s^BG"))
 
 #ifdef CSQC
 string notif_arg_frag_ping(bool newline, float fping)
index 3bc6c55636c65fa4e3875d0bf2b328e0f3a0aa02..ee762ff249246d2e0f8f79697e0a6121b4e52749 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 
-#define MAX_SCORE 64
+#define MAX_SCORE 128
 
 #define REGISTER_SP(id) REGISTER(Scores, SP, id, m_id, new_pure(PlayerScoreField))
 REGISTRY(Scores, MAX_SCORE);
@@ -85,6 +85,23 @@ REGISTER_SP(NEXBALL_FAULTS);
 
 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);
+REGISTER_SP(MEDAL_HEADSHOT);
+REGISTER_SP(MEDAL_HUMILIATION);
+REGISTER_SP(MEDAL_IMPRESSIVE);
+REGISTER_SP(MEDAL_YODA);
+
+REGISTER_SP(MEDAL_KILLSTREAK_03);
+REGISTER_SP(MEDAL_KILLSTREAK_05);
+REGISTER_SP(MEDAL_KILLSTREAK_10);
+REGISTER_SP(MEDAL_KILLSTREAK_15);
 #endif
 
 
index 9ed008c99063f29acf0926407d831ace2c065b43..ce60f0907153cb6cdb8aa2b561736f512c12ad7b 100644 (file)
@@ -23,8 +23,7 @@ void W_Devastator_Explode(entity this, entity directhitentity)
                        if(DIFF_TEAM(this.realowner, directhitentity))
                                if(!IS_DEAD(directhitentity))
                                        if(IsFlying(directhitentity)) {
-                                               //Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
-                                               Send_Notification(NOTIF_ONE, this.realowner, MSG_MEDAL, MEDAL_AIRSHOT);
+                                               Give_Medal(this.realowner, AIRSHOT);
                                        }
 
        this.event_damage = func_null;
index 10005f22e541eb41f8e472ad9ca307fe1e0cecc7..4fc98e8430cca7a45542c93af5bdd34596034686 100644 (file)
@@ -78,8 +78,9 @@ void W_Electro_Explode(entity this, entity directhitentity)
                if(IS_PLAYER(directhitentity))
                        if(DIFF_TEAM(this.realowner, directhitentity))
                                if(!IS_DEAD(directhitentity))
-                                       if(IsFlying(directhitentity))
-                                               Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_ELECTROBITCH);
+                                       if(IsFlying(directhitentity)) {
+                                               Give_Medal(this.realowner, ELECTROBITCH);
+                                       }
 
        this.event_damage = func_null;
        this.takedamage = DAMAGE_NO;
index 1f72cebbb6a7065e8788962d1891a68898203bc5..f42377191513d37c03260b4c3906f740823e6cb3 100644 (file)
@@ -9,8 +9,7 @@ void W_Mortar_Grenade_Explode(entity this, entity directhitentity)
                        if(DIFF_TEAM(this.realowner, directhitentity))
                                if(!IS_DEAD(directhitentity))
                                        if(IsFlying(directhitentity)) {
-                                               //Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
-                                               Send_Notification(NOTIF_ONE, this.realowner, MSG_MEDAL, MEDAL_AIRSHOT);
+                                               Give_Medal(this.realowner, AIRSHOT);
                                        }
 
        this.event_damage = func_null;
@@ -36,8 +35,7 @@ void W_Mortar_Grenade_Explode2(entity this, entity directhitentity)
                        if(DIFF_TEAM(this.realowner, directhitentity))
                                if(!IS_DEAD(directhitentity))
                                        if(IsFlying(directhitentity)) {
-                                               //Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
-                                               Send_Notification(NOTIF_ONE, this.realowner, MSG_MEDAL, MEDAL_AIRSHOT);
+                                               Give_Medal(this.realowner, AIRSHOT);
                                        }
 
        this.event_damage = func_null;
index 2d5ef26d100e1c767650569b845fa50f4f6e75e1..669894bdcc8296165d62d04ddad7c57e0d686229 100644 (file)
@@ -131,11 +131,13 @@ void W_Vaporizer_Attack(Weapon thiswep, entity actor, .entity weaponentity)
        W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, normalize(v - w_shotorg));
        SendCSQCVaporizerBeamParticle(actor, damage_goodhits);
 
-       if(yoda && flying)
-               Send_Notification(NOTIF_ONE, actor, MSG_MEDAL, MEDAL_YODA);
+       if(yoda && flying) {
+               Give_Medal(actor, YODA);
+       }
+               
        if(damage_goodhits && actor.vaporizer_lasthit)
        {
-               Send_Notification(NOTIF_ONE, actor, MSG_MEDAL, MEDAL_IMPRESSIVE);
+               Give_Medal(actor, IMPRESSIVE);
                damage_goodhits = 0; // only every second time
        }
 
@@ -154,8 +156,9 @@ void W_RocketMinsta_Laser_Explode (entity this, entity directhitentity)
                if(IS_PLAYER(directhitentity))
                        if(DIFF_TEAM(this.realowner, directhitentity))
                                if(!IS_DEAD(directhitentity))
-                                       if(IsFlying(directhitentity))
-                                               Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_ELECTROBITCH);
+                                       if(IsFlying(directhitentity)) {
+                                               Give_Medal(this.realowner, ELECTROBITCH);
+                                       }
 
        this.event_damage = func_null;
        this.takedamage = DAMAGE_NO;
index 55b4d56f158511de3ccb9348a6e6ba869bdbb26c..99a02720f964416b4c0cf8939e72154a88a977eb 100644 (file)
@@ -141,12 +141,13 @@ void W_Vortex_Attack(Weapon thiswep, entity actor, .entity weaponentity, float i
        damage_goodhits = 0;
        FireRailgunBullet(actor, weaponentity, w_shotorg, w_shotorg + w_shotdir * max_shot_distance, mydmg, false, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, dtype);
 
-       if(yoda && flying)
-               Send_Notification(NOTIF_ONE, actor, MSG_MEDAL, MEDAL_YODA);
+       if(yoda && flying) {
+               Give_Medal(actor, YODA);
+       }
+       
        if(damage_goodhits && actor.vortex_lasthit)
        {
-               //Send_Notification(NOTIF_ONE, actor, MSG_ANNCE, ANNCE_ACHIEVEMENT_IMPRESSIVE);
-               Send_Notification(NOTIF_ONE, actor, MSG_MEDAL, MEDAL_IMPRESSIVE);
+               Give_Medal(actor, IMPRESSIVE);
                damage_goodhits = 0; // only every second time
        }
 
index 23c4a38f43ad4264d9c7a0da5ae83dd65020e1fa..b7b346e6851d2a0d5e367b75f526fb49528dbe37 100644 (file)
@@ -263,6 +263,7 @@ bool independent_players;
 #define IS_INDEPENDENT_PLAYER(e) ((e).solid == SOLID_TRIGGER)
 #define MAKE_INDEPENDENT_PLAYER(e) (((e).solid = SOLID_TRIGGER), ((e).frags = FRAGS_PLAYER_OUT_OF_GAME))
 
+.float lastkill;
 .int killcount;
 
 //flood fields
@@ -399,6 +400,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc
 
 const int MAX_SPECTATORS = 7;
 
-#define GIVE_MEDAL(entity,medalname) \
-       Send_Notification(NOTIF_ONE, entity, MSG_ANNCE, ANNCE_ACHIEVEMENT_##medalname); \
-       Send_Notification(NOTIF_ONE, entity, MSG_MEDAL, MEDAL_##medalname);
+float _medal_times;
+#define Give_Medal(entity,medalname) \
+       _medal_times = GameRules_scoring_add(entity, MEDAL_##medalname, 1); \
+       Send_Notification(NOTIF_ONE, entity, MSG_MEDAL, MEDAL_##medalname, _medal_times);
index 06ec577e4cf74e61531833ef3d1df72954fee71a..bbb82110ececf1904c1d1e110dd16a90ba576d3c 100644 (file)
@@ -334,7 +334,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype, .en
                        // these 2 macros are spread over multiple files
                        #define SPREE_ITEM(counta,countb,center,normal,gentle) \
                                case counta: \
-                                       Send_Notification(NOTIF_ONE, attacker, MSG_MEDAL, MEDAL_KILLSTREAK_##countb); \
+                                       Give_Medal(attacker, KILLSTREAK_##countb); \
                                        if (!warmup_stage) \
                                                PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
                                        break;
@@ -350,7 +350,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype, .en
                        {
                                checkrules_firstblood = true;
                                notif_firstblood = true; // modify the current messages so that they too show firstblood information
-                               Send_Notification(NOTIF_ONE, attacker, MSG_MEDAL, MEDAL_FIRSTBLOOD);
+                               Give_Medal(attacker, FIRSTBLOOD);
                                PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
                                PlayerStats_GameReport_Event_Player(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
 
@@ -363,6 +363,12 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype, .en
                                kill_count_to_attacker = CS(attacker).killcount;
                                kill_count_to_target = 0;
                        }
+                       
+                       // Excellent check
+                       if(attacker.lastkill && attacker.lastkill > time - 2) {
+                               Give_Medal(attacker, EXCELLENT);
+                       }
+                       attacker.lastkill = time;
 
                        if(targ.istypefrag)
                        {
index 02a637ca005aea0f233fc22145286ba1cfa92c7a..27473a24cd93f3449652df7f5760304a7d1aca80 100644 (file)
@@ -63,6 +63,7 @@ float damage_gooddamage;
 .float spawnshieldtime;
 
 .int totalfrags;
+.float lastkill;
 
 .bool canteamdamage;
 
index c375d397e1adc91d690b8f063d344a3442ac51da..99b55083b0fb760cfd8cacb44377f4a0f9f75189 100644 (file)
@@ -276,8 +276,8 @@ float PlayerScore_Clear(entity player)
        sk = CS(player).scorekeeper;
        FOREACH(Scores, true, {
                if(sk.(scores(it)) != 0)
-                       if(scores_label(it) != "")
-                               sk.SendFlags |= (2 ** (i % 16));
+                       //if(scores_label(it) != "")
+                       sk.SendFlags |= (2 ** (i % 16));
                if(i != SP_ELO.m_id)
                        sk.(scores(it)) = 0;
        });
@@ -294,8 +294,8 @@ void Score_ClearAll()
                if (!sk) continue;
                FOREACH(Scores, true, {
                        if(sk.(scores(it)) != 0)
-                               if(scores_label(it) != "")
-                                       sk.SendFlags |= (2 ** (i % 16));
+                               //if(scores_label(it) != "")
+                               sk.SendFlags |= (2 ** (i % 16));
                        if(i != SP_ELO.m_id)
                                sk.(scores(it)) = 0;
                });
@@ -308,8 +308,8 @@ void Score_ClearAll()
                for(int j = 0; j < MAX_TEAMSCORE; ++j)
                {
                        if(sk.(teamscores(j)) != 0)
-                               if(teamscores_label(j) != "")
-                                       sk.SendFlags |= (2 ** j);
+                               //if(teamscores_label(j) != "")
+                               sk.SendFlags |= (2 ** j);
                        sk.(teamscores(j)) = 0;
                }
        }
@@ -356,8 +356,8 @@ float PlayerScore_Add(entity player, PlayerScoreField scorefield, float score)
        {
                return s.(scores(scorefield));
        }
-       if(scores_label(scorefield) != "")
-               s.SendFlags |= (2 ** (scorefield.m_id % 16));
+       //if(scores_label(scorefield) != "")
+       s.SendFlags |= (2 ** (scorefield.m_id % 16));
        if(!warmup_stage)
                PlayerStats_GameReport_Event_Player(s.owner, strcat(PLAYERSTATS_TOTAL, scores_label(scorefield)), score);
        s.(scores(scorefield)) += score;
index f4de0e1bf15996ac12aed1a31e64652493d96822..7c9bfb4332d77ee72ca1bc861556c391f713e201 100644 (file)
@@ -329,8 +329,9 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector
 
        IL_CLEAR(g_railgunhit);
 
-       if(headshot)
-               Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_HEADSHOT);
+       if(headshot) {
+               Give_Medal(this, HEADSHOT);
+       }
 
        // calculate hits and fired shots for hitscan
        if(this.(weaponentity))
@@ -484,8 +485,9 @@ void fireBullet_antilag(entity this, .entity weaponentity, vector start, vector
                        Damage_DamageInfo(start, 0, 0, 0, max(1, force) * normalize(dir) * -damage_fraction, dtype, 0, this);
        }
 
-       if(headshot)
-               Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_HEADSHOT);
+       if(headshot) {
+               Give_Medal(this, HEADSHOT);
+       }
 
        if(lag)
                antilag_restore_all(this);