float centerprint_medal_expire_time;
string centerprint_medal_icon;
-int centerprint_medal_times;
+float centerprint_medal_times;
bool centerprint_title_show;
string centerprint_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);
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;
}
vector duel_score_fontsize;
vector duel_name_fontsize;
vector duel_score_size;
+int total_medals;
float sbt_bg_alpha;
float sbt_fg_alpha;
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;
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;
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) {
"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),
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;
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)
{
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);
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)
--- /dev/null
+#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;
+}
+
--- /dev/null
+#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
+}
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
}
// 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
string icon,
Notification anncename)
{
+ notif.nent_floatcount = 1;
if (icon != "") { notif.nent_icon = strzone(icon); }
if (anncename) { notif.nent_msgannce = anncename; }
}
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)
{
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;
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;
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;
{
#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
#ifdef CSQC
case MSG_MEDAL:
{
- Local_Notification_Queue_Add(net_type, notif, 3);
+ Local_Notification_Queue_Add(
+ net_type,
+ notif,
+ 3,
+ f1);
break;
}
#endif
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;
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)
#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);
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
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;
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;
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;
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;
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
}
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;
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
}
#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
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);
// 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;
{
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);
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)
{
.float spawnshieldtime;
.int totalfrags;
+.float lastkill;
.bool canteamdamage;
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;
});
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;
});
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;
}
}
{
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;
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))
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);