float weapontime;
float weaponprevtime;
+float timer;
float teamnagger;
int hudShiftState;
float current_player;
+ float autocvar__menu_alpha; // updated by the menu VM, useful to tell when the menu is being drawn
+
+ string autocvar__hud_panelorder;
+
+ bool autocvar_hud_cursormode = true;
+ string autocvar_hud_dock;
+ float autocvar_hud_dock_alpha;
+ string autocvar_hud_dock_color;
+ bool autocvar_hud_dock_color_team;
+ string autocvar_hud_panel_bg;
+ float autocvar_hud_panel_bg_alpha;
+ float autocvar_hud_panel_bg_border;
+ vector autocvar_hud_panel_bg_color;
+ float autocvar_hud_panel_bg_color_team;
+ float autocvar_hud_panel_bg_padding;
+ float autocvar_hud_panel_fg_alpha;
+ string autocvar_hud_skin;
+ float autocvar_hud_progressbar_alpha;
+ float autocvar_hud_panel_update_interval;
+
float autocvar_hud_dynamic_follow;
float autocvar_hud_dynamic_follow_scale;
vector autocvar_hud_dynamic_follow_scale_xyz;
REGISTER_HUD_PANEL(QUICKMENU, HUD_QuickMenu, PANEL_CONFIG_MAIN , PANEL_SHOW_MAINGAME | PANEL_SHOW_MINIGAME ) // QUICKMENU
REGISTER_HUD_PANEL(SCOREBOARD, Scoreboard_Draw, PANEL_CONFIG_NO , PANEL_SHOW_MAINGAME | PANEL_SHOW_MINIGAME | PANEL_SHOW_MAPVOTE | PANEL_SHOW_WITH_SB) // SCOREBOARD
REGISTER_HUD_PANEL(STRAFEHUD, HUD_StrafeHUD, PANEL_CONFIG_MAIN | PANEL_CONFIG_CANBEOFF, PANEL_SHOW_MAINGAME ) // STRAFEHUD
+REGISTER_HUD_PANEL(SPECTHUD, HUD_SpectHUD, PANEL_CONFIG_NO | PANEL_CONFIG_CANBEOFF, PANEL_SHOW_MAINGAME) // SPECTHUD
// always add new panels to the end of list
// Because calling lots of functions in QC apparently cuts fps in half on many machines:
#pragma once
#include "../panel.qh"
-float autocvar_hud_panel_centerprint_fade_in = 0.2;
+ bool autocvar_hud_panel_centerprint;
+ float autocvar_hud_panel_centerprint_align;
-float autocvar_hud_panel_centerprint_fade_subsequent_minfontsize = 0.75;
-float autocvar_hud_panel_centerprint_fade_minfontsize = 0;
++//float autocvar_hud_panel_centerprint_fade_in = 0.2;
+ float autocvar_hud_panel_centerprint_fade_out = 0.5;
+ float autocvar_hud_panel_centerprint_fade_subsequent = 1;
+ float autocvar_hud_panel_centerprint_fade_subsequent_passone = 3;
+ float autocvar_hud_panel_centerprint_fade_subsequent_passone_minalpha = 0.5;
+ float autocvar_hud_panel_centerprint_fade_subsequent_passtwo = 10;
+ float autocvar_hud_panel_centerprint_fade_subsequent_passtwo_minalpha = 0.5;
++//float autocvar_hud_panel_centerprint_fade_subsequent_minfontsize = 0.75;
++//float autocvar_hud_panel_centerprint_fade_minfontsize = 0;
+ bool autocvar_hud_panel_centerprint_flip;
+ float autocvar_hud_panel_centerprint_fontscale;
+ float autocvar_hud_panel_centerprint_fontscale_bold = 1.4;
+ bool autocvar_hud_panel_centerprint_dynamichud = true;
+ float autocvar_hud_panel_centerprint_time;
+
+void centerprint_ClearTitle();
+void centerprint_SetTitle(string title);
+void centerprint_Medal(string icon, int times);
++
void centerprint_Add(int new_id, string strMessage, float duration, int countdown_num);
void centerprint_AddStandard(string strMessage);
void centerprint_Kill(int id);
#include "chat.qh"
- #include <client/autocvars.qh>
#include <client/draw.qh>
+#include <common/items/inventory.qh>
// Chat (#12)
cvar_set("con_chatwidth", ftos(mySize.x/vid_conwidth));
cvar_set("con_chat", ftos(floor(mySize.y/autocvar_con_chatsize - 0.5)));
+ vector chatsize = '1 1 0' * autocvar_con_chatsize;
if(autocvar__hud_configure)
{
- vector chatsize = '1 1 0' * autocvar_con_chatsize;
cvar_set("con_chatrect_x", "9001"); // over 9000, we'll fake it instead for more control over alpha and such
string str = textShortenToWidth(_("^3Player^7: This is the chat area."), mySize.x, chatsize, stringwidth_colors);
for(int i = 0; i < autocvar_con_chat; ++i)
pos.y += chatsize.y;
}
}
+
+ // z411 items
+ float stat_last_pickup = STAT(LAST_PICKUP);
+ pos.y += mySize.y;
+ entity it = last_pickup_item;
+
+ if(stat_last_pickup && stat_last_pickup > time - 3 && it) {
+ float a, y;
+ string str1, str2, icon;
+ vector sz, sz2;
+ vector pickupsize = chatsize * 1.25;
+ vector iconsize = chatsize * 2;
+
+ icon = strcat(hud_skin_path, "/", ((it.model2) ? it.model2 : it.m_icon));
+ sz = draw_getimagesize(icon);
+ sz2 = vec2(iconsize.y*(sz.x/sz.y), iconsize.y);
+ str1 = seconds_tostring(last_pickup_timer);
+ str2 = ((last_pickup_times > 1) ? sprintf("%s (x%d)", it.m_name, last_pickup_times) : it.m_name);
+ y = (iconsize.y - pickupsize.y) / 2;
+
+ if(time < stat_last_pickup + 3 - 0.5)
+ a = 1;
+ else
+ a = (stat_last_pickup + 3 - time) / 0.5;
+
+ drawstring(pos + eY * y, str1, pickupsize, '1 1 1', a, DRAWFLAG_NORMAL);
+ pos.x += stringwidth(str1, false, pickupsize) + pickupsize.x * 0.25;
+ drawpic(pos, icon, sz2, '1 1 1', a, DRAWFLAG_NORMAL);
+ pos.x += sz2.x + pickupsize.x * 0.25;
+ drawstring(pos + eY * y, str2, pickupsize, '1 1 1', a, DRAWFLAG_NORMAL);
+ }
}
#include "infomessages.qh"
- #include <client/autocvars.qh>
#include <client/draw.qh>
#include <common/ent_cs.qh>
{
if(spectatee_status)
{
- if(spectatee_status == -1)
+ /*if(spectatee_status == -1)
s = _("^1Observing");
else
s = sprintf(_("^1Spectating: ^7%s"), entcs_GetName(current_player));
- InfoMessage(s);
+ InfoMessage(s);*/
if(autocvar_hud_panel_infomessages_group0)
{
InfoMessage(s);
}
- bool mutator_returnvalue = MUTATOR_CALLHOOK(DrawInfoMessages, pos, mySize, img_curr_group);
- pos = M_ARGV(0, vector);
- img_curr_group = M_ARGV(2, int);
+ //bool mutator_returnvalue = MUTATOR_CALLHOOK(DrawInfoMessages, pos, mySize, img_curr_group);
+ //pos = M_ARGV(0, vector);
+ //img_curr_group = M_ARGV(2, int);
- if(!mutator_returnvalue)
- {
+ //if(!mutator_returnvalue)
+ //{
s = sprintf(_("^1Press ^3%s^1 to join"), getcommandkey(_("jump"), "+jump"));
InfoMessage(s);
- }
+ //}
}
if (time < STAT(GAMESTARTTIME))
InfoMessage(s);
}
}
+
+ // z411
+ MUTATOR_CALLHOOK(DrawInfoMessages, pos, mySize, img_curr_group);
}
else
{
#include "modicons.qh"
- #include <client/autocvars.qh>
#include <client/draw.qh>
#include <common/ent_cs.qh>
#include <common/gamemodes/_mod.qh>
if(!autocvar_hud_panel_modicons) return;
if(!HUD_ModIcons_GameType) return;
}
-
+
if(mod_active || autocvar__hud_configure)
mod_alpha = min(mod_alpha + frametime * 2, 1);
else
#include "score.qh"
- #include <client/autocvars.qh>
#include <client/draw.qh>
#include <client/hud/panel/scoreboard.qh>
#include <common/ent_cs.qh>
}
void HUD_Score_Rankings(vector pos, vector mySize, entity me)
-{
+{
float score;
entity tm = NULL, pl;
int SCOREPANEL_MAX_ENTRIES = 6;
}
return;
}
-
- if (!scoreboard_fade_alpha) // the scoreboard too calls Scoreboard_UpdatePlayerTeams
- Scoreboard_UpdatePlayerTeams();
+
+ /*
if (team_count)
{
// show team scores in the first line
first_pl = 1;
pos.y += fontsize.y;
tm = teams.sort_next;
- }
- i = first_pl;
-
- do
- for (pl = players.sort_next; pl && i<entries; pl = pl.sort_next)
+ }*/
+
+
+ // z411 Basic team stats
+ if (team_count)
{
- if ((team_count && pl.team != tm.team) || pl.team == NUM_SPECTATOR)
- continue;
-
- if (i == entries-1 && !me_printed && pl != me)
- if (autocvar_hud_panel_score_rankings == 1 && spectatee_status != -1)
- {
- for (pl = me.sort_next; pl; pl = pl.sort_next)
- if (pl.team != NUM_SPECTATOR)
- break;
+ i = 0;
+ for(tm = teams.sort_next; tm; tm = tm.sort_next) {
+ if(tm.team == NUM_SPECTATOR)
+ continue;
+ if(!tm.team)
+ continue;
- if (pl)
- rgb = '1 1 0'; //not last but not among the leading players: yellow
- else
- rgb = '1 0 0'; //last: red
- pl = me;
+ /*if (tm.team == myteam)
+ drawfill(pos + eX * score_size * i, vec2(score_size, fontsize.y), '1 1 1', highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(pos + eX * score_size * i, ftos(tm.(teamscores(ts_primary))), vec2(score_size, fontsize.y), Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
+ ++i;*/
+
+ if (tm.team == myteam)
+ {
+ if (i == 0)
+ rgb = '0 1 0'; //first: green
+ me_printed = true;
+ drawfill(pos, eX * mySize.x + eY * fontsize.y, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
+ }
+
+ score_color = Team_ColorRGB(tm.team) * 0.8;
+
+ // TODO secondary scores test, remove
+ if(gametype.m_modscores)
+ {
+ string icon;
+ if(tm.team == NUM_TEAM_1)
+ icon = "gfx/hud/luma/player_red";
+ else if(tm.team == NUM_TEAM_2)
+ icon = "gfx/hud/luma/player_blue";
+ else
+ icon = "gfx/hud/luma/player_neutral";
+
+ vector icon_sz = draw_getimagesize(icon);
+ vector icon_sz_new = vec2(fontsize.y*(icon_sz.x/icon_sz.y), fontsize.y);
+
+ s = ftos(gametype.m_modscores(tm.team));
+ float s_width = stringwidth(s, false, fontsize) + icon_sz_new.x;
+
+ //drawfill(pos, eX * s_width + eY * fontsize.y, score_color, panel_fg_alpha * 0.3, DRAWFLAG_NORMAL);
+ drawpic(pos, icon, icon_sz_new, '1 1 1', panel_fg_alpha * 0.7, DRAWFLAG_NORMAL);
+ drawstring(pos + eX * icon_sz_new.x, s, fontsize, '1 1 1', panel_fg_alpha * 0.7, DRAWFLAG_NORMAL);
+
+ s = textShortenToWidth(Team_CustomName(tm.team), name_size - s_width, fontsize, stringwidth_colors);
+ } else
+ s = textShortenToWidth(Team_CustomName(tm.team), name_size, fontsize, stringwidth_colors);
+ // TODO end
+
+ drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, true, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ draw_beginBoldFont();
+ drawstring(pos + eX * (name_size + spacing_size), ftos(tm.(teamscores(ts_primary))), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
+ draw_endBoldFont();
+
+ pos.y += fontsize.y;
+ ++i;
}
-
- if (pl == me)
+ } else {
+ i = first_pl;
+
+ do
+ for (pl = players.sort_next; pl && i<entries; pl = pl.sort_next)
{
- if (i == first_pl)
- rgb = '0 1 0'; //first: green
- me_printed = true;
- drawfill(pos, eX * mySize.x + eY * fontsize.y, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
+ if ((team_count && pl.team != tm.team) || pl.team == NUM_SPECTATOR)
+ continue;
+
+ if (i == entries-1 && !me_printed && pl != me)
+ if (autocvar_hud_panel_score_rankings == 1 && spectatee_status != -1)
+ {
+ for (pl = me.sort_next; pl; pl = pl.sort_next)
+ if (pl.team != NUM_SPECTATOR)
+ break;
+
+ if (pl)
+ rgb = '1 1 0'; //not last but not among the leading players: yellow
+ else
+ rgb = '1 0 0'; //last: red
+ pl = me;
+ }
+
+ if (team_count)
+ score_color = Team_ColorRGB(pl.team) * 0.8;
+
+ entity entcs = entcs_receiver(pl.sv_entnum);
+ if(entcs.m_entcs_private) {
+ // z411 draw health/armor bar
+ vector bar_sz = vec2(mySize.x, fontsize.y);
+
+ bar_sz.x *= entcs.healthvalue / autocvar_hud_panel_healtharmor_maxhealth;
+ drawfill(pos, bar_sz, ((team_count) ? score_color : '0.8 0.8 0'), 0.5, DRAWFLAG_NORMAL);
+
+ bar_sz.x *= GetResource(entcs, RES_ARMOR) / autocvar_hud_panel_healtharmor_maxarmor;
+ drawfill(pos + eY * (bar_sz.y * 0.7), bar_sz - eY * (bar_sz.y * 0.7), ((team_count) ? score_color : '0 0.8 0.8'), 1, DRAWFLAG_NORMAL);
+ }
+
+ if (pl == me)
+ {
+ if (i == first_pl)
+ rgb = '0 1 0'; //first: green
+ me_printed = true;
+ drawfill(pos, eX * mySize.x + eY * fontsize.y, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
+ }
+
+ s = textShortenToWidth(entcs_GetName(pl.sv_entnum), name_size, fontsize, stringwidth_colors);
+ drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, true, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring(pos + eX * (name_size + spacing_size), ftos(pl.(scores(ps_primary))), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
+ pos.y += fontsize.y;
+ ++i;
}
- if (team_count)
- score_color = Team_ColorRGB(pl.team) * 0.8;
- s = textShortenToWidth(entcs_GetName(pl.sv_entnum), name_size, fontsize, stringwidth_colors);
- drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, true, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring(pos + eX * (name_size + spacing_size), ftos(pl.(scores(ps_primary))), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
- pos.y += fontsize.y;
- ++i;
+ while (i<entries && team_count && (tm = tm.sort_next) && (tm.team != NUM_SPECTATOR || (tm = tm.sort_next)));
}
- while (i<entries && team_count && (tm = tm.sort_next) && (tm.team != NUM_SPECTATOR || (tm = tm.sort_next)));
}
void HUD_Score()
if(!autocvar_hud_panel_score) return;
if(MUTATOR_CALLHOOK(HUD_Score_show)) return;
}
+
+ if (!scoreboard_fade_alpha) // the scoreboard too calls Scoreboard_UpdatePlayerTeams
+ Scoreboard_UpdatePlayerTeams();
+
+ if(spectatee_status && teamplay) return;
HUD_Panel_LoadCvars();
vector pos, mySize;
#include "scoreboard.qh"
- #include <client/autocvars.qh>
#include <client/draw.qh>
+ #include <client/hud/panel/chat.qh>
#include <client/hud/panel/quickmenu.qh>
#include <client/hud/panel/racetimer.qh>
#include <client/hud/panel/weapons.qh>
#include <common/scores.qh>
#include <common/stats.qh>
#include <common/teams.qh>
+#include <common/items/inventory.qh>
// Scoreboard (#24)
string hud_fontsize_str;
float max_namesize;
+vector duel_score_fontsize;
+vector duel_name_fontsize;
+vector duel_score_size;
+vector team_score_fontsize;
+vector team_name_fontsize;
+vector team_score_size;
+int total_medals;
+
float sbt_bg_alpha;
float sbt_fg_alpha;
float sbt_fg_alpha_self;
bool autocvar_hud_panel_scoreboard_spectators_aligned = false;
float autocvar_hud_panel_scoreboard_minwidth = 0.4;
+int average_ping[NUM_TEAMS];
+
// mode 0: returns translated label
// mode 1: prints name and description of all the labels
string Label_getInfo(string label, int mode)
sbt_num_fields = 0;
hud_fontsize = HUD_GetFontsize("hud_fontsize");
+
+ duel_score_fontsize = hud_fontsize * 3;
+ duel_name_fontsize = hud_fontsize * 1.5;
+ duel_score_size = vec2(duel_score_fontsize.x * 1.5, duel_score_fontsize.y * 1.25);
+
+ team_score_fontsize = hud_fontsize * 2;
+ team_name_fontsize = hud_fontsize * 1.5;
+ team_score_size = vec2(team_score_fontsize.x * 1.5, team_score_fontsize.y * 1.25);
for(i = 1; i < argc - 1; ++i)
{
{
sbt_field_icon0 = "gfx/scoreboard/player_ready";
}
- else if(!teamplay)
+ /*else if(!teamplay)
{
int f = entcs_GetClientColors(pl.sv_entnum);
{
sbt_field_icon2 = "gfx/scoreboard/playercolor_pants";
sbt_field_icon2_rgb = colormapPaletteColor(f % 16, 1);
}
+ }*/
+ else
+ {
+ int ccode = entcs_GetCountryCode(pl.sv_entnum);
+ if(ccode)
+ sbt_field_icon0 = strcat("gfx/flags/", ftos(ccode));
}
+
return entcs_GetName(pl.sv_entnum);
}
+vector getPingColor(float f)
+{
+ if(f < 80) {
+ // 20-80 range is green
+ return '0 1 0' + '1 0 1' * max(0, min(60, f-20)) / 60;
+ } else {
+ // 80-300 range is red
+ return '1 1 1' - '0 1 1' * max(0, min(220, f-80)) / 220;
+ }
+}
string Scoreboard_GetField(entity pl, PlayerScoreField field)
{
float tmp, num, denom;
f = pl.ping;
if(f == 0)
return _("N/A");
- tmp = max(0, min(220, f-80)) / 220;
- sbt_field_rgb = '1 1 1' - '0 1 1' * tmp;
+ sbt_field_rgb = getPingColor(f);
+
return ftos(f);
+ //return ftos(pl.team);
case SP_PL:
if (!pl.gotscores)
}
}
-vector Scoreboard_DrawHeader(vector pos, vector rgb, bool other_players)
+vector Scoreboard_DrawHeader(vector pos, vector rgb, bool other_players, int team)
{
int i;
+ string title_str;
+ vector title_rgb;
vector column_dim = eY * panel_size.y;
+
if(other_players)
column_dim.y -= 1.25 * hud_fontsize.y;
vector text_offset = eY * (1.25 - 1) / 2 * hud_fontsize.y;
{
if(sbt_field[i] == SP_SEPARATOR)
break;
+
+ vector text_offset_center = '0 0 0';
+
+ if(sbt_field[i] == SP_PING && teamplay) {
+ title_str = sprintf("(%d)", average_ping[Team_TeamToIndex(team) - 1]);
+ title_rgb = getPingColor(average_ping[Team_TeamToIndex(team) - 1]);
+ text_offset_center.x = sbt_field_size[i] - stringwidth(title_str, false, hud_fontsize);
+ } else {
+ title_str = sbt_field_title[i];
+ title_rgb = rgb * 1.5;
+ }
+
column_dim.x = sbt_field_size[i] + hud_fontsize.x;
if (sbt_highlight)
if (i % 2)
drawfill(pos - eX * hud_fontsize.x * 0.5, column_dim, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
- drawstring(pos + text_offset, sbt_field_title[i], hud_fontsize, rgb * 1.5, sbt_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring(pos + text_offset + text_offset_center, title_str, hud_fontsize, title_rgb, sbt_fg_alpha, DRAWFLAG_NORMAL);
pos.x += column_dim.x;
}
if(sbt_field[i] == SP_SEPARATOR)
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;
+ vector tmp_sz, tmp_sz2;
+ string picpath;
+
+ // Icon
+ if(skinned) {
+ picpath = strcat(hud_skin_path, "/", icon);
+ if(precache_pic(picpath) == "")
+ picpath = strcat("gfx/hud/default/", icon);
+ } else {
+ picpath = icon;
+ }
+
+ tmp_sz = draw_getimagesize(picpath);
+ tmp_sz2 = vec2(sz.y*(tmp_sz.x/tmp_sz.y), sz.y);
+
+ tmp_in.x = pos.x + ((sz.x - tmp_sz2.x) / 2);
+ drawpic(tmp_in, picpath, tmp_sz2, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ // Number
+ if(invert)
+ tmp_in.x += tmp_sz2.x + hud_fontsize.x * 0.25;
+ 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,
+ ((number == -1) ? "?" : ftos(number)),
+ hud_fontsize, ((number > 0) ? '1 1 1' : '0.5 0.5 0.5'),
+ panel_fg_alpha,
+ DRAWFLAG_NORMAL);
+
+ pos.y += sz.y * 1.1;
+ return pos;
+}
+
+void Scoreboard_Duel_DrawTable(vector pos, bool invert, entity pl, entity tm)
+{
+ vector tmp, tmp_in, tmp_sz, tmp_acc;
+ string tmp_str;
+ float sz;
+ float average_acc = 0;
+
+ panel_pos = pos;
+
+ HUD_Panel_DrawBg();
+
+ // Stop here if there are no scores available
+ if(pl.team != tm.team) return;
+
+ tmp = pos;
+ tmp.x += panel_bg_padding;
+ tmp.y += panel_bg_padding;
+ panel_size.x -= panel_bg_padding * 2;
+
+ //if (sbt_bg_alpha)
+ // drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", tmp, panel_size, rgb, sbt_bg_alpha, DRAWFLAG_NORMAL);
+
+ // Score: highlight
+ if(invert) { tmp.x += panel_size.x; tmp.x -= duel_score_size.x; }
+ drawfill(tmp, duel_score_size, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
+
+ // Score: text
+ tmp_str = ftos(pl.(scores(SP_SCORE)));
+ tmp_in = tmp;
+ tmp_in.x += (duel_score_size.x / 2) - (stringwidth(tmp_str, true, duel_score_fontsize) / 2);
+ tmp_in.y += (duel_score_size.y / 2) - (duel_score_fontsize.y / 2);
+
+ draw_beginBoldFont();
+ drawstring(tmp_in, tmp_str, duel_score_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ draw_endBoldFont();
+
+ // Player name
+ tmp_str = Scoreboard_GetField(pl, SP_NAME);
+ tmp_in = tmp;
+ if(invert)
+ tmp_in.x -= stringwidth_colors(tmp_str, duel_name_fontsize) + duel_name_fontsize.x * 0.5;
+ else
+ tmp_in.x += duel_score_size.x + duel_name_fontsize.x * 0.5;
+ tmp_in.y += (duel_score_size.y - duel_name_fontsize.y) / 2;
+ drawcolorcodedstring(tmp_in, tmp_str, duel_name_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ // Player icon/flag
+ if(sbt_field_icon0 != "") {
+ vector rsz = draw_getimagesize(sbt_field_icon0);
+ sbt_fixcolumnwidth_iconlen = rsz.x / rsz.y;
+ if(invert)
+ tmp_in.x -= hud_fontsize.x * sbt_fixcolumnwidth_iconlen + duel_name_fontsize.x * 0.5;
+ else
+ tmp_in.x += stringwidth_colors(tmp_str, duel_name_fontsize) + duel_name_fontsize.x * 0.5;
+ tmp_in.y += (duel_name_fontsize.y - hud_fontsize.y) / 2;
+ drawpic(tmp_in, sbt_field_icon0, vec2(hud_fontsize.x * sbt_fixcolumnwidth_iconlen, hud_fontsize.y), sbt_field_icon1_rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
+ }
+
+ // Header
+ float column_width = panel_size.x / 5;
+ tmp.x = pos.x + panel_bg_padding;
+ tmp.y += hud_fontsize.y * 3 + hud_fontsize.y;
+
+ vector column_dim;
+ int i;
+
+ i = (invert ? 4 : 0);
+ column_dim = vec2(column_width * 4, hud_fontsize.y);
+
+ drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth("kills", false, hud_fontsize) / 2),
+ "kills", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth("dmg", false, hud_fontsize) / 2),
+ "dmg", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth("acc", false, hud_fontsize) / 2),
+ "acc", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth("hits", false, hud_fontsize) / 2),
+ "hits", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth("ping", false, hud_fontsize) / 2),
+ "ping", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ tmp.x = pos.x + panel_bg_padding;
+ tmp.y += hud_fontsize.y;
+
+ // Main row
+ i = (invert ? 4 : 0);
+
+ tmp_str = ftos(pl.(scores(SP_KILLS)));
+ drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth(tmp_str, false, hud_fontsize * 1.25) / 2),
+ tmp_str, hud_fontsize * 1.25, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ tmp_str = ftos(pl.(scores(SP_DMG)));
+ drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth(tmp_str, false, hud_fontsize * 1.25) / 2),
+ tmp_str, hud_fontsize * 1.25, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ tmp_acc = tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2);
+
+ if(invert)
+ i--;
+ else
+ i++;
+
+ tmp_str = Scoreboard_GetField(pl, SP_PING);
+ drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth(tmp_str, false, hud_fontsize * 1.25) / 2),
+ tmp_str, hud_fontsize * 1.25, sbt_field_rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ tmp.x = pos.x + panel_bg_padding;
+ tmp.y += hud_fontsize.y * 2;
+
+ tmp_in = tmp;
+
+ int total_weapons = 0;
+
+ // Accuracy rows
+ WepSet weapons_inmap = WepSet_GetFromStat_InMap();
+ FOREACH(Weapons, it != WEP_Null, {
+ WepSet set = it.m_wepset;
+ if (!(weapons_inmap & set))
+ continue;
+ if (it.spawnflags & WEP_TYPE_OTHER)
+ continue;
+
+ int weapon_cnt_fired = pl.accuracy_cnt_fired[i - WEP_FIRST];
+ int weapon_cnt_hit = pl.accuracy_cnt_hit[i - WEP_FIRST];
+ int weapon_acc = 0;
+ if(weapon_cnt_fired)
+ weapon_acc = floor((weapon_cnt_hit / weapon_cnt_fired) * 100);
+ average_acc += weapon_acc;
+
+ string draw_str;
+
+ // weapon stats
+ int c = (invert ? 4 : 0);
+
+ drawfill(tmp_in + eX * column_width * (invert ? 1 : 0), column_dim, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
+
+ 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, (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, (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, (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, (weapon_cnt_fired ? '1 1 1' : '0.5 0.5 0.5'), panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ // weapon icon
+ if(invert) {
+ tmp_in.x = pos.x + panel_size.x - panel_bg_padding - hud_fontsize.x / 2;
+ drawpic_aspect_skin(tmp_in, it.model2, vec2(50, hud_fontsize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ }
+
+ tmp_in.x = pos.x + panel_bg_padding;
+ tmp_in.y += hud_fontsize.y * 1.25;
+
+ if(weapon_cnt_fired)
+ total_weapons++;
+ });
+ if(total_weapons)
+ average_acc = floor((average_acc / total_weapons) + 0.5);
+
+ // draw total accuracy now
+ tmp_str = sprintf("%d%%", average_acc);
+ drawstring(tmp_acc - eX * (stringwidth(tmp_str, false, hud_fontsize * 1.25) / 2),
+ tmp_str, hud_fontsize * 1.25, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ // Icon column
+ vector icon_sz = vec2(column_width, hud_fontsize.y*1.5);
+
+ if(!invert)
+ tmp.x += column_width * 4;
+ // Medal rows
+ drawstring(tmp + eX * ((column_width - stringwidth("medals", false, hud_fontsize)) / 2),
+ "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/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),
+ "items", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ tmp.y += hud_fontsize.y * 1.25;
+
+ float inv_num = -1;
+ FOREACH(Items,
+ it.m_id == ITEM_ArmorMega.m_id ||
+ it.m_id == ITEM_HealthMega.m_id ||
+ it.m_id == ITEM_ArmorBig.m_id, {
+ // If the match isn't over, Only show pickups if we're spectating or they're our own
+ if(intermission || warmup_stage || spectatee_status || pl.sv_entnum == current_player)
+ inv_num = inventoryslots[pl.sv_entnum].inv_items[it.m_id];
+ tmp = Scoreboard_Duel_DrawPickup(tmp, true, it.m_icon, icon_sz, inv_num, invert);
+
+ if(it.m_id == REGISTRY_MAX(Items))
+ break;
+ });
+}
+vector Scoreboard_MakeDuelTable(vector pos, entity tm, vector rgb, vector bg_size)
+{
+ vector end_pos = pos;
+ float screen_half = panel_size.x / 2;
+ float weapon_margin = hud_fontsize.x;
+
+ panel_size.x = screen_half - weapon_margin;
+ panel_size.y = (duel_score_size.y * 5.5);
+
+ entity pl_left = players.sort_next;
+ entity pl_right = pl_left.sort_next;
+
+ Scoreboard_Duel_DrawTable(pos, true, pl_left, tm);
+ Scoreboard_Duel_DrawTable(pos + eX * screen_half + eX * weapon_margin, false, pl_right, tm);
+
+ end_pos.y += panel_size.y + (panel_bg_padding * 2);
+ panel_size.x = screen_half * 2;
+ return end_pos;
+}
+
vector Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_size)
{
int max_players = 999;
// print header row and highlight columns
- pos = Scoreboard_DrawHeader(panel_pos, rgb, (max_players < tm.team_size));
+ pos = Scoreboard_DrawHeader(panel_pos, rgb, (max_players < tm.team_size), tm.team);
// fill the table and draw the rows
bool is_self = false;
bool self_shown = false;
int i = 0;
+ int with_ping = 0;
+ if(Team_IsValidTeam(tm.team)) average_ping[Team_TeamToIndex(tm.team) - 1] = 0;
for(pl = players.sort_next; pl; pl = pl.sort_next)
{
if(pl.team != tm.team)
}
is_self = (pl.sv_entnum == current_player);
Scoreboard_DrawItem(pos, rgb, pl, is_self, i);
+
+ if(Team_IsValidTeam(tm.team) && pl.ping) {
+ average_ping[Team_TeamToIndex(tm.team) - 1] += pl.ping;
+ ++with_ping;
+ }
if(is_self)
self_shown = true;
pos.y += 1.25 * hud_fontsize.y;
++i;
}
+ if(with_ping) average_ping[Team_TeamToIndex(tm.team) - 1] /= with_ping;
panel_size.x += panel_bg_padding * 2; // restore initial width
return end_pos;
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/damage", height, pl.(scores(SP_MEDAL_DAMAGE)));
+ 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)));
+
+ pos.x += hud_fontsize.x;
+
+ pos = Scoreboard_DrawMedal(pos, "gfx/medal/accuracy", height, pl.(scores(SP_MEDAL_ACCURACY)));
+ pos = Scoreboard_DrawMedal(pos, "gfx/medal/assist", height, pl.(scores(SP_MEDAL_ASSIST)));
+ pos = Scoreboard_DrawMedal(pos, "gfx/medal/defense", height, pl.(scores(SP_MEDAL_DEFENSE)));
+ pos = Scoreboard_DrawMedal(pos, "gfx/medal/perfect", height, pl.(scores(SP_MEDAL_PERFECT)));
+
+ 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)
{
return pos;
}
+/*
vector Scoreboard_MapStats_Draw(vector pos, vector rgb, vector bg_size) {
float stat_secrets_found, stat_secrets_total;
float stat_monsters_killed, stat_monsters_total;
panel_size.x += panel_bg_padding * 2; // restore initial width
return end_pos;
}
-
+*/
vector Scoreboard_Rankings_Draw(vector pos, string ranktitle, entity pl, vector rgb, vector bg_size)
{
sb_gameinfo_type_fontsize = hud_fontsize * 2.5;
sb_gameinfo_detail_fontsize = hud_fontsize * 1.3;
+ // z411 server name
+ //drawcolorcodedstring(pos, "bienvenidoainternet.org", sb_gameinfo_type_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+ //drawpic_aspect(pos + '1 0 0' * (panel_size.x - 150), "gfx/bai_logo", vec2(150, sb_gameinfo_type_fontsize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ //pos.y += sb_gameinfo_type_fontsize.y;
+
// Game Info: Game Type
str = MapInfo_Type_ToText(gametype);
+
draw_beginBoldFont();
- drawcolorcodedstring(pos + '0.5 0 0' * (panel_size.x - stringwidth(str, true, sb_gameinfo_type_fontsize)), str, sb_gameinfo_type_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+ //drawcolorcodedstring(pos + '0.5 0 0' * (panel_size.x - stringwidth(str, true, sb_gameinfo_type_fontsize)), str, sb_gameinfo_type_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawcolorcodedstring(pos, str, sb_gameinfo_type_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
draw_endBoldFont();
+
+ vector tmp_old_sz = draw_getimagesize("gfx/bai_logo");
+ float tmp_aspect = tmp_old_sz.x/tmp_old_sz.y;
+ vector tmp_new_sz = vec2(sb_gameinfo_type_fontsize.y * tmp_aspect, sb_gameinfo_type_fontsize.y);
+ drawpic(pos + '1 0 0' * (panel_size.x - tmp_new_sz.x), "gfx/bai_logo", tmp_new_sz, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ pos.y += sb_gameinfo_type_fontsize.y;
+
+ // z411 servername
+ drawcolorcodedstring(pos + '0.5 0 0' * (panel_size.x - stringwidth_colors(hostname_full, sb_gameinfo_detail_fontsize)), hostname_full, sb_gameinfo_detail_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ pos.y += sb_gameinfo_detail_fontsize.y;
+
// Game Info: Game Detail
float tl = STAT(TIMELIMIT);
float fl = STAT(FRAGLIMIT);
}
}
- pos.y += sb_gameinfo_type_fontsize.y;
drawcolorcodedstring(pos + '1 0 0' * (panel_size.x - stringwidth(str, true, sb_gameinfo_detail_fontsize)), str, sb_gameinfo_detail_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); // align right
// map name
str = sprintf(_("^7Map: ^2%s"), shortmapname);
if (autocvar_hud_panel_scoreboard_team_size_position != 1) // team size not on left
{
// put team score to the left of scoreboard (and team size to the right)
- team_score_baseoffset = eY * hud_fontsize.y - eX * hud_fontsize.x * 0.5;
+ team_score_baseoffset = eY * hud_fontsize.y - eX * hud_fontsize.x * 1.5;
team_size_baseoffset = eY * hud_fontsize.y + eX * hud_fontsize.x * 0.5;
if(panel.current_panel_bg != "0")
{
else
{
// put team score to the right of scoreboard (and team size to the left)
- team_score_baseoffset = eY * hud_fontsize.y + eX * hud_fontsize.x * 0.5;
+ team_score_baseoffset = eY * hud_fontsize.y + eX * hud_fontsize.x * 1.5;
team_size_baseoffset = eY * hud_fontsize.y - eX * hud_fontsize.x * 0.5;
if(panel.current_panel_bg != "0")
{
if(!tm.team)
continue;
- draw_beginBoldFont();
vector rgb = Team_ColorRGB(tm.team);
+ /*draw_beginBoldFont();
str = ftos(tm.(teamscores(ts_primary)));
if (autocvar_hud_panel_scoreboard_team_size_position != 1) // team size not on left
{
// team score on the left (default)
- str_pos = pos + team_score_baseoffset - eX * stringwidth(str, false, hud_fontsize * 1.5);
+ str_pos = pos + team_score_baseoffset - eX * stringwidth(str, false, hud_fontsize * 3);
}
else
{
// team score on the right
- str_pos = pos + team_score_baseoffset + eX * (panel_size.x + hud_fontsize.x * 1.5);
+ str_pos = pos + team_score_baseoffset + eX * (panel_size.x + hud_fontsize.x * 3);
}
- drawstring(str_pos, str, hud_fontsize * 1.5, rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring(str_pos, str, hud_fontsize * 3, rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
// team size (if set to show on the side)
if (autocvar_hud_panel_scoreboard_team_size_position != 0) // team size not off
drawstring(str_pos, str, hud_fontsize, rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
}
draw_endBoldFont();
+ */
+
+ // z411 My team header
+ // Score: highlight
+ drawfill(pos, team_score_size, rgb * 0.5, sbt_highlight_alpha, DRAWFLAG_NORMAL);
+
+ // Score: text
+ str = ftos(tm.(teamscores(ts_primary)));
+ str_pos = pos;
+ str_pos.x += (team_score_size.x / 2) - (stringwidth(str, true, team_score_fontsize) / 2);
+ str_pos.y += (team_score_size.y / 2) - (team_score_fontsize.y / 2);
+
+ draw_beginBoldFont();
+ drawstring(str_pos, str, team_score_fontsize, rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
+ draw_endBoldFont();
+
+ // Team name
+ str = Team_CustomName(tm.team);
+ str_pos = pos;
+ str_pos.x += team_score_size.x + team_name_fontsize.x * 0.5;
+ str_pos.y += (team_score_size.y / 2) - (team_name_fontsize.y / 2);
+ drawcolorcodedstring(str_pos, str, team_name_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ pos.y += team_score_size.y + (hud_fontsize.y * 0.5);
+
if(autocvar_hud_panel_scoreboard_bg_teams_color_team > 0)
panel_bg_color = rgb * autocvar_hud_panel_scoreboard_bg_teams_color_team;
else if(panel_bg_color_team > 0)
}
panel_bg_color = panel_bg_color_save;
}
+ else if(gametype == MAPINFO_TYPE_DUEL)
+ {
+ for(tm = teams.sort_next; tm; tm = tm.sort_next)
+ if(tm.team != NUM_SPECTATOR)
+ break;
+
+ // z411 make DUEL TABLE
+ pos = Scoreboard_MakeDuelTable(pos, tm, panel_bg_color, bg_size);
+ }
else
{
for(tm = teams.sort_next; tm; tm = tm.sort_next)
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);
pos = Scoreboard_Rankings_Draw(pos, ranktitle, playerslots[player_localnum], panel_bg_color, bg_size);
}
- pos = Scoreboard_MapStats_Draw(pos, panel_bg_color, bg_size);
+ //pos = Scoreboard_MapStats_Draw(pos, panel_bg_color, bg_size);
// List spectators
for(pl = players.sort_next; pl; pl = pl.sort_next)
--- /dev/null
- #include <client/autocvars.qh>
+#include "spect.qh"
+
+#include <client/hud/hud.qh>
+#include <client/view.qh>
+
+vector teamscore_size;
+vector teamscore_fontsize;
+vector teamname_fontsize;
+
+void HUD_SpectHUD_Export(int fh)
+{
+ // allow saving cvars that aesthetically change the panel into hud skin files
+}
+
+void HUD_SpectHUD_drawCurrentName(vector pos)
+{
+ string s = entcs_GetName(current_player);
+ pos.x -= stringwidth_colors(s, hud_fontsize * 2) / 2;
+ drawcolorcodedstring(pos, s, hud_fontsize * 2, panel_fg_alpha, DRAWFLAG_NORMAL);
+}
+
+void HUD_SpectHUD_drawTeamPlayers(vector pos, entity tm, vector rgb, bool invert)
+{
+ vector tmp_over;
+ vector line_sz = vec2((vid_conwidth - 1) / 7, hud_fontsize.y * 1.5);
+ vector line_sz_sub = vec2((vid_conwidth - 1) / 7, hud_fontsize.y);
+
+ string playername;
+ float a = panel_fg_alpha * 0.8;
+ entity pl;
+
+ if(invert)
+ pos.x -= line_sz.x + hud_fontsize.x;
+ else
+ pos.x += hud_fontsize.x;
+
+ for(pl = players.sort_next; pl; pl = pl.sort_next)
+ {
+ if(pl.team != tm.team)
+ continue;
+
+ float health = 0;
+ float armor = 0;
+ string icon = "";
+ vector icon_size = '0 0 0';
+ vector icon_rgb = '1 1 1';
+
+ // Position and size calculation vectors
+ tmp_over = pos;
+ vector total_sz = vec2(line_sz.x, line_sz.y + line_sz_sub.y);
+
+ if(pl.eliminated) {
+ // z411 TODO : Unhardcode luma
+ icon = "gfx/hud/luma/notify_death.tga";
+ icon_rgb = rgb;
+ } else {
+ entity entcs = entcs_receiver(pl.sv_entnum);
+ if(entcs.m_entcs_private) {
+ health = (entcs.healthvalue / autocvar_hud_panel_healtharmor_maxhealth) * line_sz.x;
+ armor = (GetResource(entcs, RES_ARMOR) / autocvar_hud_panel_healtharmor_maxarmor) * line_sz_sub.x;
+
+ Weapon wep = REGISTRY_GET(Weapons, entcs.activewepid);
+ icon = strcat("gfx/hud/luma/", wep.model2);
+ } else {
+ if(tm.team == NUM_TEAM_1)
+ icon = "gfx/hud/luma/player_red";
+ else if(tm.team == NUM_TEAM_2)
+ icon = "gfx/hud/luma/player_blue";
+ else
+ icon = "gfx/hud/luma/player_neutral";
+ }
+ }
+
+ // Draw weapon
+ if(icon != "") {
+ vector tmp_sz = draw_getimagesize(icon);
+ icon_size = vec2(total_sz.y*(tmp_sz.x/tmp_sz.y), total_sz.y);
+ total_sz.x += icon_size.x;
+
+ if(invert) {
+ pos.x -= icon_size.x;
+ tmp_over.x -= icon_size.x;
+ }
+ drawpic(pos, icon, icon_size, icon_rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
+ pos.x += icon_size.x;
+ }
+
+ // Get player's name
+ playername = textShortenToWidth(entcs_GetName(pl.sv_entnum), line_sz.x * 0.8, hud_fontsize, stringwidth_colors);
+
+ // Draw health and name
+ drawfill(pos, line_sz, rgb * 0.7, a * 0.3, DRAWFLAG_NORMAL);
+ if(health)
+ drawfill(pos, vec2(health, line_sz.y), rgb * 0.7, a, DRAWFLAG_NORMAL);
+ drawcolorcodedstring(pos + eY * ((line_sz.y - hud_fontsize.y) / 2) + eX * (hud_fontsize.x * 0.5), playername, hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+ pos.y += line_sz.y;
+
+ // Draw armor
+ if(armor)
+ drawfill(pos, vec2(armor, line_sz_sub.y), rgb, a, DRAWFLAG_NORMAL);
+
+ // Highlight current player
+ if(pl.sv_entnum == current_player && spectatee_status != -1)
+ drawfill(tmp_over, total_sz, '1 1 1', 0.3, DRAWFLAG_NORMAL);
+ if(pl.eliminated)
+ drawfill(tmp_over, total_sz, '0 0 0', 0.4, DRAWFLAG_NORMAL);
+
+ if(!invert)
+ pos.x -= icon_size.x;
+ pos.y += line_sz_sub.y * 2;
+ }
+}
+
+
+void HUD_SpectHUD_drawTeamScore(vector pos, entity tm, vector rgb, bool invert)
+{
+ if(!tm) return;
+
+ vector tmp;
+ string tmp_str;
+
+ // Team score
+ tmp_str = ftos(tm.(teamscores(ts_primary)));
+
+ if(invert)
+ pos.x -= teamscore_size.x;
+
+ drawfill(pos, teamscore_size, rgb * 0.8, 0.3, DRAWFLAG_NORMAL);
+
+ tmp = pos;
+ tmp.x += (teamscore_size.x - stringwidth(tmp_str, true, teamscore_fontsize)) / 2;
+ tmp.y += (teamscore_size.y - teamscore_fontsize.y) / 2;
+
+ draw_beginBoldFont();
+ drawstring(tmp, tmp_str, teamscore_fontsize, rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
+ draw_endBoldFont();
+
+ // Team name
+ tmp_str = Team_CustomName(tm.team);
+
+ tmp = pos;
+ if(invert)
+ tmp.x -= stringwidth_colors(tmp_str, teamname_fontsize) + teamname_fontsize.x * 0.5;
+ else
+ tmp.x += teamscore_size.x + teamname_fontsize.x * 0.5;
+ tmp.y += (teamscore_size.y - teamname_fontsize.y) / 2;
+
+ drawcolorcodedstring(tmp, tmp_str, teamname_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+}
+
+void HUD_SpectHUD()
+{
+ if(!spectatee_status) return;
+
+ vector pos, rgb;
+ float ammo_y, timer_width;
+ entity tm;
+
+ // Set main vars
+ HUD_Panel_LoadCvars();
+ HUD_Scale_Enable();
+ hud_fontsize = HUD_GetFontsize("hud_fontsize");
+
+ // Spectator name
+ if(spectatee_status != -1) {
+ ammo_y = stov(cvar_string("hud_panel_ammo_pos")).y * vid_conheight;
+ pos = panel_pos + vec2((vid_conwidth - 1) / 2, (ammo_y - (hud_fontsize.y * 2)));
+ HUD_SpectHUD_drawCurrentName(pos);
+ }
+
+ if(!teamplay) return;
+
+ // Set vars
+ teamscore_fontsize = hud_fontsize * 3;
+ teamname_fontsize = hud_fontsize * 2;
+ teamscore_size = vec2(teamscore_fontsize.x * 1.5, teamscore_fontsize.y * 1.25);
+ timer_width = stov(cvar_string("hud_panel_timer_size")).x * vid_conwidth;
+
+ // Team 1
+ pos = panel_pos + vec2((vid_conwidth - 1) / 2, 0);
+ tm = GetTeam(NUM_TEAM_1, false);
+ rgb = Team_ColorRGB(tm.team);
+ pos.x -= (timer_width * 1.3) / 2;
+ HUD_SpectHUD_drawTeamScore(pos, tm, rgb, true);
+
+ pos = panel_pos + vec2(0, (vid_conheight - 1) / 4 + hud_fontsize.y);
+ HUD_SpectHUD_drawTeamPlayers(pos, tm, rgb, false);
+
+ // Team 2
+ pos = panel_pos + vec2((vid_conwidth - 1) / 2, 0);
+ tm = GetTeam(NUM_TEAM_2, false);
+ rgb = Team_ColorRGB(tm.team);
+ pos.x += (timer_width * 1.3) / 2;
+ HUD_SpectHUD_drawTeamScore(pos, tm, rgb, false);
+
+ pos = panel_pos + vec2(vid_conwidth - 1, (vid_conheight - 1) / 4 + hud_fontsize.y);
+ HUD_SpectHUD_drawTeamPlayers(pos, tm, rgb, true);
+}
#include "timer.qh"
- #include <client/autocvars.qh>
- #include <client/hud/hud.qh>
+ #include <client/draw.qh>
#include <client/view.qh>
// Timer (#5)
mySize -= '2 2 0' * panel_bg_padding;
}
- string timer;
- float timelimit, timeleft, minutesLeft;
+ string timer_sub = "";
+ bool game_timeout;
+ float timelimit, timeleft, minutesLeft, overtimes, timeout_last;
timelimit = STAT(TIMELIMIT);
+ overtimes = STAT(OVERTIMESADDED);
+ game_timeout = STAT(GAME_TIMEOUT);
+ timeout_last = STAT(TIMEOUT_LAST);
timeleft = max(0, timelimit * 60 + STAT(GAMESTARTTIME) - time);
timeleft = ceil(timeleft);
timer_color = '1 0 0'; //red
if (intermission_time) {
- timer = seconds_tostring(max(0, floor(intermission_time - STAT(GAMESTARTTIME))));
- } else if (warmup_stage && warmup_timeleft >= 60) {
- timer = _("WARMUP");
- } else if (autocvar_hud_panel_timer_increment || (!warmup_stage && timelimit == 0) || (warmup_stage && warmup_timeleft <= 0)) {
- if (time < STAT(GAMESTARTTIME))
- timer = seconds_tostring(0); //while restart is still active, show 00:00
+ timer = max(0, floor(intermission_time - STAT(GAMESTARTTIME)));
+ timer_sub = "Intermission";
+ //} else if (autocvar_hud_panel_timer_increment || (!warmup_stage && timelimit == 0) || (warmup_stage && warmup_timeleft <= 0)) {
+ } else if (game_timeout) {
+ if(autocvar_hud_panel_timer_increment)
+ timer = max(0, floor(timeout_last - STAT(GAMESTARTTIME)));
else
- timer = seconds_tostring(floor(time - STAT(GAMESTARTTIME)));
- } else {
- if(warmup_stage)
- timer = seconds_tostring(warmup_timeleft);
+ timer = ceil(max(0, timelimit * 60 + STAT(GAMESTARTTIME) - timeout_last));
+ timer_sub = "Timeout";
+ } else if (autocvar_hud_panel_timer_increment || timelimit == 0) {
+ // Time elapsed timer
+ if((warmup_stage && warmup_timeleft <= 0) || time < STAT(GAMESTARTTIME))
+ timer = 0;
else
- timer = seconds_tostring(timeleft);
+ timer = floor(time - STAT(GAMESTARTTIME));
+ } else {
+ // Time left timer
+ if(warmup_stage) {
+ if(warmup_timeleft <= 0)
+ timer = floor(timelimit * 60);
+ else
+ timer = warmup_timeleft;
+ } else {
+ if (time < STAT(GAMESTARTTIME))
+ timer = floor(timelimit * 60);
+ //else if (overtimes > 0)
+ // timer = floor(time - STAT(OVERTIMESTARTTIME));
+ else
+ timer = timeleft;
+ }
+ }
+
+ if(warmup_stage)
+ timer_sub = "Warmup";
+ else if(overtimes == 1)
+ timer_sub = "Overtime";
+ else if (overtimes > 1)
+ timer_sub = sprintf("Overtime #%d", overtimes);
+
+ drawstring_aspect(pos, seconds_tostring(timer), mySize, timer_color, panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ if(timer_sub != "") {
+ pos.y += mySize.y;
+ mySize.y = mySize.y / 2;
+ drawstring_aspect(pos, timer_sub, mySize, '1 0 0', panel_fg_alpha, DRAWFLAG_NORMAL);
}
-
- drawstring_aspect(pos, timer, mySize, timer_color, panel_fg_alpha, DRAWFLAG_NORMAL);
draw_endBoldFont();
}
#include "weapons.qh"
- #include <client/autocvars.qh>
#include <client/draw.qh>
#include <client/view.qh>
#include <common/wepent.qh>
bool weapons_orderbyimpulse_old;
void HUD_Weapons()
{
+ if(spectatee_status && teamplay) return; // z411
+
// declarations
WepSet weapons_stat = WepSet_GetFromStat();
int i;
}
// draw the weapon accuracy
- if(autocvar_hud_panel_weapons_accuracy)
+ /* z411 if(autocvar_hud_panel_weapons_accuracy)
{
float panel_weapon_accuracy = weapon_accuracy[it.m_id-WEP_FIRST];
if(panel_weapon_accuracy >= 0)
color = Accuracy_GetColor(panel_weapon_accuracy);
drawpic_aspect_skin(weapon_pos, "weapon_accuracy", weapon_size, color, panel_fg_alpha, DRAWFLAG_NORMAL);
}
- }
+ }*/
vector weapon_size_real = noncurrent_size;
float weapon_alpha_real = noncurrent_alpha;
#include <common/constants.qh>
#include <common/weapons/_all.qh>
+#include <common/items/inventory.qh>
+
+// z411
+string hostname_full;
+ bool autocvar_cl_db_saveasdump;
+ bool autocvar_cl_spawn_event_particles;
+ bool autocvar_cl_spawn_event_sound = 1;
+ // float autocvar_cl_spawn_point_model;
+ bool autocvar_cl_spawn_point_particles;
+ float autocvar_cl_spawn_point_dist_max = 1200;
+ bool autocvar_cl_unpress_zoom_on_spawn = true;
+ bool autocvar_cl_unpress_zoom_on_death = true;
+ bool autocvar_cl_unpress_zoom_on_weapon_switch = true;
+ bool autocvar_cl_unpress_attack_on_weapon_switch = false;
+ bool autocvar_hud_showbinds;
+ bool autocvar_hud_showbinds_limit;
+ bool autocvar__hud_showbinds_reload;
+ bool autocvar_developer_csqcentities;
+ bool autocvar_cl_race_cptimes_onlyself; // TODO: move to race gamemode
+ bool autocvar_cl_race_cptimes_showself = false;
+
// Map coordinate base calculations need these
vector mi_center;
vector mi_scale;
.int enttype; // entity type sent from server
.int sv_entnum; // entity number sent from server
+// z411 accuracy info
+.float accuracy_frags[REGISTRY_MAX(Weapons)];
+.float accuracy_hit[REGISTRY_MAX(Weapons)];
+.float accuracy_cnt_hit[REGISTRY_MAX(Weapons)];
+.float accuracy_cnt_fired[REGISTRY_MAX(Weapons)];
+
.int team;
.int team_size;
+.int countrycode;
int binddb;
#include "view.qh"
#include <client/announcer.qh>
- #include <client/autocvars.qh>
#include <client/csqcmodel_hooks.qh>
#include <client/draw.qh>
#include <client/hud/_mod.qh>
float kill_time = STAT(KILL_TIME);
if (COMPARE_INCREASING(kill_time, kill_time_prev) > autocvar_cl_hitsound_antispam_time)
{
- sound(NULL, CH_INFO, SND_KILL, VOL_BASE, ATTN_NONE);
+ sound(NULL, CH_INFO, SND_KILL, VOL_BASE * 1.15, ATTN_NONE);
kill_time_prev = kill_time;
}
}
else if(STAT(FROZEN))
{
vector col = '0.25 0.90 1';
- if(STAT(REVIVE_PROGRESS))
- col += vec3(STAT(REVIVE_PROGRESS), -STAT(REVIVE_PROGRESS), -STAT(REVIVE_PROGRESS));
- drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), col, autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+ float col_fade = max(0, STAT(REVIVE_PROGRESS) * 2 - 1);
+ float alpha_fade = 0.3 + 0.7 * (1 - max(0, STAT(REVIVE_PROGRESS) * 4 - 3));
+ if(col_fade)
+ col += vec3(col_fade, -col_fade, -col_fade);
+ drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), col, autocvar_hud_colorflash_alpha * alpha_fade, DRAWFLAG_ADDITIVE);
}
HUD_Scale_Enable();
UpdateDamage();
HUD_Crosshair(this);
HitSound();
+ Local_Notification_Queue_Process();
}
void ViewLocation_Mouse()
myhealth_flash += autocvar_hud_damage_fade_rate * frametime; // dead
}
}
+
+ if(myhealth_prev > 1 && myhealth <= 0 && !intermission)
+ {
+ // Just died
+ sound(NULL, CH_INFO, SND_DEATH, VOL_BASE, ATTN_NONE);
+ }
if(spectatee_status == -1 || intermission)
{
#pragma once
- //void HUD_Mod_CA(vector myPos, vector mySize);
- //void HUD_Mod_CA_Draw(vector myPos, vector mySize, int layout);
- //void HUD_Mod_CA_Export(int fh);
-int autocvar_hud_panel_modicons_ca_layout;
-
-void HUD_Mod_CA(vector myPos, vector mySize);
-void HUD_Mod_CA_Draw(vector myPos, vector mySize, int layout);
-void HUD_Mod_CA_Export(int fh);
+int HUD_Scores_CA(int team);
#pragma once
- //void HUD_Mod_FreezeTag_Export(int fh);
-int autocvar_hud_panel_modicons_freezetag_layout;
-
-void HUD_Mod_FreezeTag_Export(int fh);
void nades_Clear(entity);
void nades_GiveBonus(entity player, float score);
+entity freezetag_LastPlayer(float tm)
+{
+ entity last_pl = NULL;
+ FOREACH_CLIENT(IS_PLAYER(it) && it.team == tm, {
+ if (STAT(FROZEN, it) != FROZEN_NORMAL && GetResource(it, RES_HEALTH) >= 1)
+ {
+ if (!last_pl)
+ last_pl = it;
+ else
+ return NULL;
+ }
+ });
+ return last_pl;
+}
+
bool freezetag_CheckWinner()
{
if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
{
Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_ROUND_OVER);
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ROUND_OVER);
+ Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_ROUND_OVER);
+
FOREACH_CLIENT(IS_PLAYER(it), {
it.freezetag_frozen_timeout = 0;
+ it.freezetag_revive_time = 0;
nades_Clear(it);
});
- game_stopped = true;
+ if(autocvar_g_freezetag_round_stop)
+ game_stopped = true;
round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
return true;
}
int winner_team = freezetag_getWinnerTeam();
if(winner_team > 0)
{
- Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN));
- Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN));
+ entity last_pl = freezetag_LastPlayer(winner_team);
+ if(last_pl) {
+ Give_Medal(last_pl, DEFENSE);
+ }
+
+ Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_SCORES));
+ Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_SCORES));
+ if(fragsleft > 1) Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, APP_TEAM_NUM(winner_team, ANNCE_ROUND_TEAM_WIN));
TeamScore_AddToTeam(winner_team, ST_FT_ROUNDS, +1);
}
else if(winner_team == -1)
{
Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_ROUND_TIED);
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ROUND_TIED);
+ Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_ROUND_TIED);
}
FOREACH_CLIENT(IS_PLAYER(it), {
it.freezetag_frozen_timeout = 0;
+ it.freezetag_revive_time = 0;
nades_Clear(it);
});
- game_stopped = true;
+ if(autocvar_g_freezetag_round_stop)
+ game_stopped = true;
round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
return true;
}
if(round_handler_IsRoundStarted())
{
entity pl = freezetag_LastPlayerForTeam(this);
- if(pl)
+ if(pl) {
Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_ALONE);
+ Send_Notification(NOTIF_ONE, pl, MSG_ANNCE, ANNCE_ALONE);
+ }
}
}
{
if(attacker == targ)
{
- // you froze your own dumb targ
+ // you froze your own dumb self
// counted as "suicide" already
GameRules_scoring_add(targ, SCORE, -1);
}
if(STAT(FROZEN, targ))
return;
- if(autocvar_g_freezetag_frozen_maxtime > 0)
+ targ.freezetag_frozen_time = time;
+ if (autocvar_g_freezetag_revive_auto && autocvar_g_freezetag_frozen_maxtime > 0)
targ.freezetag_frozen_timeout = time + autocvar_g_freezetag_frozen_maxtime;
Freeze(targ, 0, FROZEN_NORMAL, true);
{
FOREACH_CLIENT(IS_PLAYER(it), {
CS(it).killcount = 0;
- it.freezetag_revive_time = 0;
- it.freezetag_frozen_timeout = -1;
- PutClientInServer(it);
+
+ if(autocvar_g_freezetag_round_respawn) {
+ it.freezetag_frozen_timeout = -1;
+ PutClientInServer(it);
+ } else {
+ ResetPlayerResources(it);
+ }
+
it.freezetag_frozen_timeout = 0;
});
freezetag_count_alive_players();
{
entity targ = M_ARGV(0, entity);
targ.freezetag_frozen_time = 0;
+
+ if(autocvar_g_freezetag_revive_respawn) {
+ targ.freezetag_frozen_timeout = -1;
+ PutClientInServer(targ);
+ }
+
targ.freezetag_frozen_timeout = 0;
}
+ MUTATOR_HOOKFUNCTION(ft, Damage_Calculate)
+ {
+ entity frag_attacker = M_ARGV(1, entity);
+ entity frag_target = M_ARGV(2, entity);
+ //float frag_deathtype = M_ARGV(3, float);
+ //float frag_damage = M_ARGV(4, float);
+ vector frag_force = M_ARGV(6, vector);
+
+ if (STAT(FROZEN, frag_target) == FROZEN_NORMAL && autocvar_g_freezetag_revive_auto_reducible
+ && autocvar_g_freezetag_frozen_maxtime > 0 && autocvar_g_freezetag_revive_auto)
+ {
+ float t = 0;
+ if ((autocvar_g_freezetag_revive_auto_reducible < 0 || DIFF_TEAM(frag_attacker, frag_target))
+ && frag_target.freezetag_frozen_timeout > time)
+ {
+ if (fabs(autocvar_g_freezetag_revive_auto_reducible) == 1)
+ t = vlen(frag_force) * autocvar_g_freezetag_revive_auto_reducible_forcefactor;
+ frag_target.freezetag_frozen_timeout -= t;
+ if (frag_target.freezetag_frozen_timeout < time)
+ frag_target.freezetag_frozen_timeout = time;
+ }
+ }
+ }
+
#ifdef IS_REVIVING
#undef IS_REVIVING
#endif
int n = 0;
vector revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size;
FOREACH_CLIENT(IS_PLAYER(it) && IS_REVIVING(player, it, revive_extra_size), {
+ if (autocvar_g_freezetag_revive_time_to_score > 0 && STAT(FROZEN, player) == FROZEN_NORMAL)
+ {
+ it.freezetag_revive_time += frametime / autocvar_g_freezetag_revive_time_to_score;
+ while (it.freezetag_revive_time > 1)
+ {
+ GameRules_scoring_add(it, SCORE, +1);
+ it.freezetag_revive_time -= 1;
+ }
+ }
if (reviving_players_last)
reviving_players_last.chain = it;
reviving_players_last = it;
if (!n && player.freezetag_frozen_timeout > 0 && time >= player.freezetag_frozen_timeout)
n = -1;
+ float base_progress = 0;
+ if (STAT(FROZEN, player) == FROZEN_NORMAL && autocvar_g_freezetag_revive_auto
+ && autocvar_g_freezetag_frozen_maxtime > 0 && autocvar_g_freezetag_revive_auto_progress)
+ {
+ // NOTE if auto-revival is in progress, manual revive speed is reduced so that it always takes the same amount of time
+ base_progress = bound(0, (1 - (player.freezetag_frozen_timeout - time) / autocvar_g_freezetag_frozen_maxtime), 1);
+ }
+
if (!n) // no teammate nearby
{
+ float clearspeed = autocvar_g_freezetag_revive_clearspeed;
+ if (autocvar_g_freezetag_revive_time_to_score > 0)
+ clearspeed = 0; // prevent stacking points by entering and exiting the revival zone many times
if (STAT(FROZEN, player) == FROZEN_NORMAL)
- {
- STAT(REVIVE_PROGRESS, player) = bound(0, STAT(REVIVE_PROGRESS, player) - frametime * autocvar_g_freezetag_revive_clearspeed, 1);
- SetResourceExplicit(player, RES_HEALTH, max(1, STAT(REVIVE_PROGRESS, player) * ((warmup_stage) ? warmup_start_health : start_health)));
- }
+ STAT(REVIVE_PROGRESS, player) = bound(base_progress, STAT(REVIVE_PROGRESS, player) - frametime * clearspeed * (1 - base_progress), 1);
else if (!STAT(FROZEN, player))
- STAT(REVIVE_PROGRESS, player) = 0; // thawing nobody
+ STAT(REVIVE_PROGRESS, player) = base_progress; // thawing nobody
}
else if (STAT(FROZEN, player) == FROZEN_NORMAL) // OK, there is at least one teammate reviving us
{
- STAT(REVIVE_PROGRESS, player) = bound(0, STAT(REVIVE_PROGRESS, player) + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1);
- SetResourceExplicit(player, RES_HEALTH, max(1, STAT(REVIVE_PROGRESS, player) * ((warmup_stage) ? warmup_start_health : start_health)));
+ STAT(REVIVE_PROGRESS, player) = bound(base_progress, STAT(REVIVE_PROGRESS, player) + frametime * max(1/60, autocvar_g_freezetag_revive_speed * (1 - base_progress)), 1);
if(STAT(REVIVE_PROGRESS, player) >= 1)
{
+ float frozen_time = time - player.freezetag_frozen_time;
Unfreeze(player, false);
+ SetResourceExplicit(player, RES_HEALTH, ((warmup_stage) ? warmup_start_health : start_health));
freezetag_count_alive_players();
if(n == -1)
{
- Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_FREEZETAG_AUTO_REVIVED, autocvar_g_freezetag_frozen_maxtime);
- Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_FREEZETAG_AUTO_REVIVED, player.netname, autocvar_g_freezetag_frozen_maxtime);
+ Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_FREEZETAG_AUTO_REVIVED, frozen_time);
+ Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_FREEZETAG_AUTO_REVIVED, player.netname, frozen_time);
return true;
}
Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_FREEZETAG_REVIVED, first.netname);
Send_Notification(NOTIF_ONE, first, MSG_CENTER, CENTER_FREEZETAG_REVIVE, player.netname);
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_FREEZETAG_REVIVED, player.netname, first.netname);
+ Give_Medal(first, ASSIST);
}
for(entity it = reviving_players_first; it; it = it.chain)
STAT(REVIVE_PROGRESS, it) = STAT(REVIVE_PROGRESS, player);
}
+ if (STAT(FROZEN, player) == FROZEN_NORMAL)
+ {
+ entity player_wp = player.waypointsprite_attached;
+ if (n > 0 || (n == 0 && STAT(REVIVE_PROGRESS, player) > 0.95))
+ {
+ WaypointSprite_UpdateSprites(player_wp, WP_Reviving, WP_Null, WP_Null);
+ WaypointSprite_UpdateTeamRadar(player_wp, RADARICON_WAYPOINT, WP_REVIVING_COLOR);
+ }
+ else
+ {
+ WaypointSprite_UpdateSprites(player_wp, WP_Frozen, WP_Null, WP_Null);
+ WaypointSprite_UpdateTeamRadar(player_wp, RADARICON_WAYPOINT, WP_FROZEN_COLOR);
+ }
+
+ WaypointSprite_UpdateMaxHealth(player_wp, 1);
+ WaypointSprite_UpdateHealth(player_wp, STAT(REVIVE_PROGRESS, player));
+ }
+
return true;
}
bool autocvar_g_freezetag_team_spawns;
string autocvar_g_freezetag_weaponarena = "most_available";
+bool autocvar_g_freezetag_round_respawn;
+bool autocvar_g_freezetag_round_stop;
+
const int ST_FT_ROUNDS = 1;
void freezetag_Initialize();
return 0;
}
+ .float freezetag_revive_time;
.float freezetag_frozen_time;
.float freezetag_frozen_timeout;
const float ICE_MAX_ALPHA = 1;
const float ICE_MIN_ALPHA = 0.1;
float freezetag_teams;
+ bool autocvar_g_freezetag_revive_auto = 1;
+ int autocvar_g_freezetag_revive_auto_progress = 1;
+ int autocvar_g_freezetag_revive_auto_reducible;
+ float autocvar_g_freezetag_revive_auto_reducible_forcefactor;
float autocvar_g_freezetag_revive_extra_size;
float autocvar_g_freezetag_revive_speed;
+ float autocvar_g_freezetag_revive_time_to_score = 1.5;
bool autocvar_g_freezetag_revive_nade;
float autocvar_g_freezetag_revive_nade_health;
+bool autocvar_g_freezetag_revive_respawn;
const int GAMETYPE_FLAG_PREFERRED = BIT(2); // preferred (when available) in random selections
const int GAMETYPE_FLAG_PRIORITY = BIT(3); // priority selection when preferred gametype isn't available in random selections
const int GAMETYPE_FLAG_HIDELIMITS = BIT(4); // don't display a score limit needed for winning the match in the scoreboard
+ const int GAMETYPE_FLAG_WEAPONARENA = BIT(5); // gametype has a forced weapon arena, weapon arena mutators should disable themselves when this is set
int MAPINFO_TYPE_ALL;
.int m_flags;
ATTRIB(Gametype, frags, bool, true);
/** should this gametype display a score limit in the scoreboard? */
ATTRIB(Gametype, m_hidelimits, bool, false);
+ /** does this gametype enforce its own weapon arena? */
+ ATTRIB(Gametype, m_weaponarena, bool, false);
/** game type defaults */
ATTRIB(Gametype, model2, string);
/** game type description */
/** game type priority in random selections */
ATTRIB(Gametype, m_priority, int, 0);
#ifdef CSQC
- ATTRIB(Gametype, m_modicons, void(vector pos, vector mySize));
- ATTRIB(Gametype, m_modicons_reset, void());
- ATTRIB(Gametype, m_modicons_export, void(int fh));
+ //ATTRIB(Gametype, m_modicons, void(vector pos, vector mySize));
+ //ATTRIB(Gametype, m_modicons_reset, void());
+ //ATTRIB(Gametype, m_modicons_export, void(int fh));
+ ATTRIB(Gametype, m_modscores, int(int team));
#endif
/** DO NOT USE, this is compatibility for legacy maps! */
this.frags = (gflags & GAMETYPE_FLAG_USEPOINTS);
this.m_priority = ((gflags & GAMETYPE_FLAG_PREFERRED) ? 2 : ((gflags & GAMETYPE_FLAG_PRIORITY) ? 1 : 0));
this.m_hidelimits = (gflags & GAMETYPE_FLAG_HIDELIMITS);
+ this.m_weaponarena = (gflags & GAMETYPE_FLAG_WEAPONARENA);
// same as `1 << m_id`
MAPINFO_TYPE_ALL |= this.items = this.m_flags = (MAPINFO_TYPE_ALL + 1);
#include <common/mapobjects/teleporters.qh>
#include <common/mapobjects/triggers.qh>
#include <common/monsters/all.qh>
+ #include <common/mutators/mutator/nades/nades.qh>
#include <common/physics/movelib.qh>
#include <common/stats.qh>
#include <common/teams.qh>
#include <common/weapons/_mod.qh>
#include <lib/csqcmodel/sv_model.qh>
#include <lib/warpzone/common.qh>
- #include <server/autocvars.qh>
#include <server/campaign.qh>
#include <server/cheats.qh>
+ #include <server/client.qh>
#include <server/command/_mod.qh>
#include <server/damage.qh>
#include <server/items/items.qh>
void monsters_setstatus(entity this)
{
- STAT(MONSTERS_TOTAL, this) = monsters_total;
- STAT(MONSTERS_KILLED, this) = monsters_killed;
+ //STAT(MONSTERS_TOTAL, this) = monsters_total;
+ //STAT(MONSTERS_KILLED, this) = monsters_killed;
}
void monster_dropitem(entity this, entity attacker)
#include "sv_buffs.qh"
#include <common/mapobjects/target/music.qh>
+ #include <common/mutators/mutator/instagib/_mod.qh>
#include <common/gamemodes/_mod.qh>
#include <server/items/items.qh>
- void buffs_DelayedInit(entity this);
-
- AUTOCVAR(g_buffs, int, -1, "Enable buffs, -1: enabled but no auto location or replacing powerups, 1: enabled and can replace them");
-
- REGISTER_MUTATOR(buffs, autocvar_g_buffs)
- {
- MUTATOR_ONADD
- {
- if(autocvar_g_buffs > 0)
- InitializeEntity(NULL, buffs_DelayedInit, INITPRIO_FINDTARGET);
- }
- }
-
bool buffs_BuffModel_Customize(entity this, entity client)
{
entity player = WaypointSprite_getviewentity(client);
void buff_Respawn(entity this)
{
- if(game_stopped) return;
+ if(game_stopped || game_timeout) return;
vector oldbufforigin = this.origin;
this.velocity = '0 0 200';
void buff_Touch(entity this, entity toucher)
{
- if(game_stopped) return;
+ if(game_stopped || game_timeout) return;
if(ITEM_TOUCH_NEEDKILL())
{
this.oldbuffs = STAT(BUFFS, this);
}
- if(!game_stopped)
+ if(!game_stopped && !game_timeout)
if((round_handler_IsActive() && round_handler_IsRoundStarted()) || time >= game_starttime)
if(!this.buff_activetime_updated)
{
}
if(this.buff_activetime)
- if(!game_stopped)
+ if(!game_stopped && !game_timeout)
if((round_handler_IsActive() && round_handler_IsRoundStarted()) || time >= game_starttime)
{
this.buff_activetime = max(0, this.buff_activetime - frametime);
return;
}
- // note: only really useful in teamplay
- void buff_Medic_Heal(entity this)
- {
- FOREACH_CLIENT(IS_PLAYER(it) && it != this && vdist(it.origin - this.origin, <=, autocvar_g_buffs_medic_heal_range),
- {
- if (DIFF_TEAM(it, this))
- {
- continue;
- }
- float hp = GetResource(it, RES_HEALTH);
- if(hp >= autocvar_g_balance_health_regenstable)
- {
- continue;
- }
- Send_Effect(EFFECT_HEALING, it.origin, '0 0 0', 1);
- SetResource(it, RES_HEALTH, bound(0, hp + autocvar_g_buffs_medic_heal_amount, autocvar_g_balance_health_regenstable));
- });
- }
-
float buff_Inferno_CalculateTime(float damg, float offset_x, float offset_y, float intersect_x, float intersect_y, float base)
{
return offset_y + (intersect_y - offset_y) * logn(((damg - offset_x) * ((base - 1) / intersect_x)) + 1, base);
Fire_AddDamage(frag_target, frag_attacker, (frag_damage * autocvar_g_buffs_inferno_damagemultiplier), btime, DEATH_BUFF.m_id);
}
- // this... is ridiculous (TODO: fix!)
- if(STAT(BUFFS, frag_attacker) & BUFF_VAMPIRE.m_itemid)
- if(!frag_target.vehicle)
- if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
- if(!IS_DEAD(frag_target))
- if(IS_PLAYER(frag_target) || IS_MONSTER(frag_target))
- if(frag_attacker != frag_target)
- if(!STAT(FROZEN, frag_target))
- if(frag_target.takedamage)
- if(DIFF_TEAM(frag_attacker, frag_target))
- {
- float amount = bound(0, frag_damage * autocvar_g_buffs_vampire_damage_steal,
- GetResource(frag_target, RES_HEALTH));
- GiveResourceWithLimit(frag_attacker, RES_HEALTH, amount, g_pickup_healthsmall_max);
- if (GetResource(frag_target, RES_ARMOR))
- {
- amount = bound(0, frag_damage * autocvar_g_buffs_vampire_damage_steal,
- GetResource(frag_target, RES_ARMOR));
- GiveResourceWithLimit(frag_attacker, RES_ARMOR, amount, g_pickup_armorsmall_max);
- }
- }
-
M_ARGV(4, float) = frag_damage;
M_ARGV(6, vector) = frag_force;
}
+ MUTATOR_HOOKFUNCTION(buffs, PlayerDamage_SplitHealthArmor)
+ {
+ entity frag_attacker = M_ARGV(1, entity);
+ entity frag_target = M_ARGV(2, entity);
+ if(!(STAT(BUFFS, frag_attacker) & BUFF_VAMPIRE.m_itemid))
+ return;
+ float health_take = bound(0, M_ARGV(4, float), GetResource(frag_target, RES_HEALTH));
+
+ if(time >= frag_target.spawnshieldtime &&
+ frag_target != frag_attacker &&
+ IS_PLAYER(frag_attacker) &&
+ !IS_DEAD(frag_target) && !STAT(FROZEN, frag_target))
+ {
+ GiveResource(frag_attacker, RES_HEALTH,
+ autocvar_g_buffs_vampire_damage_steal * health_take);
+ }
+ }
+
MUTATOR_HOOKFUNCTION(buffs, PlayerSpawn)
{
entity player = M_ARGV(0, entity);
MUTATOR_HOOKFUNCTION(buffs, ForbidThrowCurrentWeapon)
{
- if(MUTATOR_RETURNVALUE || game_stopped) return;
+ if(MUTATOR_RETURNVALUE || game_stopped || game_timeout) return;
entity player = M_ARGV(0, entity);
if(STAT(BUFFS, player) & BUFF_SWAPPER.m_itemid)
{
entity player = M_ARGV(0, entity);
- if(game_stopped || IS_DEAD(player) || frametime || !IS_PLAYER(player)) return;
+ if(game_stopped || game_timeout || IS_DEAD(player) || frametime || !IS_PLAYER(player)) return;
if(STAT(BUFFS, player) & BUFF_FLIGHT.m_itemid)
{
if((STAT(BUFFS, player) & BUFF_INVISIBLE.m_itemid) && (player.oldbuffs & BUFF_INVISIBLE.m_itemid))
player.alpha = ((autocvar_g_buffs_invisible_alpha) ? autocvar_g_buffs_invisible_alpha : -1); // powerups reset alpha, so we must enforce this (TODO)
- if(STAT(BUFFS, player) & BUFF_MEDIC.m_itemid)
- if(time >= player.buff_medic_healtime)
- {
- buff_Medic_Heal(player);
- player.buff_medic_healtime = time + autocvar_g_buffs_medic_heal_delay;
- }
-
#define BUFF_ONADD(b) if ( (STAT(BUFFS, player) & (b).m_itemid) && !(player.oldbuffs & (b).m_itemid))
#define BUFF_ONREM(b) if (!(STAT(BUFFS, player) & (b).m_itemid) && (player.oldbuffs & (b).m_itemid))
}
}
}
+
+ void buffs_Initialize()
+ {
+ // if buffs are above 0, allow random spawning
+ if(autocvar_g_buffs > 0 && autocvar_g_buffs_spawn_count > 0)
+ InitializeEntity(NULL, buffs_DelayedInit, INITPRIO_FINDTARGET);
+ }
#define N___NEVER 0
#define N_GNTLOFF 1
#define N__ALWAYS 2
+#define ANNCE_DEFTIME 2
-#define MULTITEAM_ANNCE(prefix, defaultvalue, sound, channel, volume, position) \
+#define MULTITEAM_ANNCE(prefix, defaultvalue, sound, channel, volume, position, queuetime) \
NOTIF_ADD_AUTOCVAR(ANNCE_##prefix, defaultvalue) \
- MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_1, prefix##_RED, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_1)), channel, volume, position) \
- MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_2, prefix##_BLUE, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_2)), channel, volume, position) \
- MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_3, prefix##_YELLOW, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_3)), channel, volume, position) \
- MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_4, prefix##_PINK, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_4)), channel, volume, position)
+ MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_1, prefix##_RED, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_1)), channel, volume, position, queuetime) \
+ MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_2, prefix##_BLUE, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_2)), channel, volume, position, queuetime) \
+ MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_3, prefix##_YELLOW, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_3)), channel, volume, position, queuetime) \
+ MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_4, prefix##_PINK, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_4)), channel, volume, position, queuetime)
// 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_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(ACHIEVEMENT_YODA, N_GNTLOFF, "yoda", 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(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(INSTAGIB_TERMINATED, N_GNTLOFF, "terminated", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(MULTIFRAG, N___NEVER, "multifrag", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_6, N__ALWAYS, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_7, N__ALWAYS, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_8, N__ALWAYS, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_9, N__ALWAYS, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_10, N__ALWAYS, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_GAMESTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_IDLE_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_IDLE_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_IDLE_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_IDLE_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_IDLE_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_IDLE_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_IDLE_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_IDLE_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_IDLE_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_IDLE_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_KILL_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_RESPAWN_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(PREPARE, N__ALWAYS, "prepareforbattle", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(REMAINING_FRAG_1, N_GNTLOFF, "1fragleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(REMAINING_FRAG_2, N_GNTLOFF, "2fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(REMAINING_FRAG_3, N_GNTLOFF, "3fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(REMAINING_MIN_1, N__ALWAYS, "1minuteremains", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(REMAINING_MIN_5, N__ALWAYS, "5minutesremain", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(TIMEOUT, N__ALWAYS, "timeoutcalled", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(VOTE_ACCEPT, N__ALWAYS, "voteaccept", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(VOTE_CALL, N__ALWAYS, "votecall", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(VOTE_FAIL, N__ALWAYS, "votefail", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_AIRSHOT, N_GNTLOFF, "airshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_AMAZING, N_GNTLOFF, "amazing", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_ASSIST, N_GNTLOFF, "assist", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_AWESOME, N_GNTLOFF, "awesome", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_DAMAGE, N_GNTLOFF, "damage", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_DEFENSE, N_GNTLOFF, "defense", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_EXCELLENT, N_GNTLOFF, "excellent", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_BOTLIKE, N_GNTLOFF, "botlike", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ 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_ANNCE_NOTIF(HEADSHOT, N__ALWAYS, "headshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(HUMILIATION, N__ALWAYS, "humiliation", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(KILLSTREAK_03, N_GNTLOFF, "03kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(KILLSTREAK_05, N_GNTLOFF, "05kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(KILLSTREAK_10, N_GNTLOFF, "10kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(KILLSTREAK_15, N_GNTLOFF, "15kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(INSTAGIB_LASTSECOND, N_GNTLOFF, "lastsecond", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(INSTAGIB_NARROWLY, N_GNTLOFF, "narrowly", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(INSTAGIB_TERMINATED, N_GNTLOFF, "terminated", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(MULTIFRAG, N_GNTLOFF, "multifrag", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(FIRSTBLOOD, N_GNTLOFF, "firstblood", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(NUM_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_6, N__ALWAYS, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_7, N__ALWAYS, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_8, N__ALWAYS, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_9, N__ALWAYS, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_10, N__ALWAYS, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(NUM_IDLE_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(NUM_KILL_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(PREPARE, N__ALWAYS, "prepareforbattle", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(PREPARE_TEAM, N__ALWAYS, "prepareyourteam", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(REMAINING_FRAG_1, N_GNTLOFF, "1fragleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(REMAINING_FRAG_2, N_GNTLOFF, "2fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(REMAINING_FRAG_3, N_GNTLOFF, "3fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(REMAINING_MIN_1, N__ALWAYS, "1minuteremains", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(REMAINING_MIN_5, N__ALWAYS, "5minutesremain", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(TIMEOUT, N__ALWAYS, "timeoutcalled", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(OVERTIME, N__ALWAYS, "overtime", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(SUDDENDEATH, N__ALWAYS, "suddendeath", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(SUICIDE, N_GNTLOFF, "suicide", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(ACCIDENT, N_GNTLOFF, "accident", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(VOTE_ACCEPT, N__ALWAYS, "voteaccept", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(VOTE_CALL, N__ALWAYS, "votecall", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(VOTE_FAIL, N__ALWAYS, "votefail", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(LEAD_GAINED, N__ALWAYS, "leadgained", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(LEAD_LOST, N__ALWAYS, "leadlost", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(LEAD_TIED, N__ALWAYS, "leadtied", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MULTITEAM_ANNCE(ROUND_TEAM_WIN, N__ALWAYS, "round_win_%s", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MULTITEAM_ANNCE(ROUND_TEAM_SCORES, N__ALWAYS, "scores_%s", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MULTITEAM_ANNCE(WINS, N__ALWAYS, "wins_%s", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ROUND_OVER, N__ALWAYS, "round_over", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ROUND_TIED, N__ALWAYS, "round_tied", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ALONE, N__ALWAYS, "alone", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+// MSG_MEDAL_NOTIFICATIONS
+
+#define MSG_MEDAL_TIME 2
+#define MSG_MEDAL_FADE_TIME 0.5
+#define MSG_MEDAL_SCREEN 10
+
+ 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(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)
+ MSG_MEDAL_NOTIF(KILLSTREAK_15, N__ALWAYS, "killstreak_15", ANNCE_KILLSTREAK_15)
+
#undef N___NEVER
#undef N_GNTLOFF
MSG_INFO_NOTIF(FREEZETAG_SELF, N_CONSOLE, 1, 0, "s1", "", "", _("^BG%s^K1 froze themself"), "")
MULTITEAM_INFO(ROUND_TEAM_WIN, N_CONSOLE, 0, 0, "", "", "", _("^TC^TT^BG team wins the round"), "", NAME)
+ MULTITEAM_INFO(ROUND_TEAM_SCORES, N_CONSOLE, 0, 0, "", "", "", _("^TC^TT^BG scores"), "", NAME)
MSG_INFO_NOTIF(ROUND_PLAYER_WIN, N_CONSOLE, 1, 0, "s1", "", "", _("^BG%s^BG wins the round"), "")
MSG_INFO_NOTIF(ROUND_TIED, N_CONSOLE, 0, 0, "", "", "", _("^BGRound tied"), "")
MSG_INFO_NOTIF(ROUND_OVER, N_CONSOLE, 0, 0, "", "", "", _("^BGRound over, there's no winner"), "")
MSG_INFO_NOTIF(POWERUP_STRENGTH, N_CONSOLE, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up Strength"), "")
MSG_INFO_NOTIF(QUIT_DISCONNECT, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 disconnected"), "")
+ MSG_INFO_NOTIF(QUIT_KICK, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 was kicked"), "")
MSG_INFO_NOTIF(QUIT_KICK_IDLING, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 was kicked for idling"), "")
MSG_INFO_NOTIF(QUIT_KICK_SPECTATING, N_CONSOLE, 0, 0, "", "", "", _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment."), "")
MSG_INFO_NOTIF(QUIT_KICK_TEAMKILL, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 was kicked for excessive teamkilling"), "")
#define MURDER_FRAG strcat(BOLD_OPERATOR, _("^K3%sYou fragged ^BG%s"))
#define MURDER_FRAG2 strcat(BOLD_OPERATOR, _("^K3%sYou scored against ^BG%s"))
+ #define MURDER_FRAG3 strcat(BOLD_OPERATOR, _("^K3%sYou fragged ^BG%s"), "\n", "%s^BG place with %s")
#define MURDER_FRAGGED _("^K1%sYou were fragged by ^BG%s")
#define MURDER_FRAGGED2 _("^K1%sYou were scored against by ^BG%s")
MSG_CENTER_NOTIF(DEATH_MURDER_FRAG, N_ENABLE, 1, 1, "spree_cen s1", CPID_Null, "0 0", MURDER_FRAG, MURDER_FRAG2 )
+ MSG_CENTER_NOTIF(DEATH_MURDER_DM, N_ENABLE, 1, 2, "spree_cen s1 frag_pos f2", CPID_Null, "0 0", MURDER_FRAG3, "")
MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED, N_ENABLE, 1, 1, "spree_cen s1", CPID_Null, "0 0", MURDER_FRAGGED, MURDER_FRAGGED2 )
MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED_VERBOSE, N_ENABLE, 1, 4, "spree_cen s1 frag_stats", CPID_Null, "0 0", VERBOSE_MURDER(FRAGGED), VERBOSE_MURDER(FRAGGED2) )
MSG_CENTER_NOTIF(DEATH_MURDER_FRAG_VERBOSE, N_ENABLE, 1, 2, "spree_cen s1 frag_ping", CPID_Null, "0 0", VERBOSE_MURDER(FRAG), VERBOSE_MURDER(FRAG2) )
MSG_CENTER_NOTIF(FREEZETAG_REVIVE, N_ENABLE, 1, 0, "s1", CPID_Null, "0 0", _("^K3You revived ^BG%s"), "")
MSG_CENTER_NOTIF(FREEZETAG_REVIVE_SELF, N_ENABLE, 0, 0, "", CPID_Null, "0 0", _("^K3You revived yourself"), "")
MSG_CENTER_NOTIF(FREEZETAG_REVIVED, N_ENABLE, 1, 0, "s1", CPID_Null, "0 0", _("^K3You were revived by ^BG%s"), "")
- MSG_CENTER_NOTIF(FREEZETAG_AUTO_REVIVED, N_ENABLE, 0, 1, "f1", CPID_Null, "0 0", _("^K3You were automatically revived after %s seconds"), "")
+ MSG_CENTER_NOTIF(FREEZETAG_AUTO_REVIVED, N_ENABLE, 0, 1, "f1", CPID_Null, "0 0", _("^BGYou were automatically revived after %s seconds"), "")
MSG_CENTER_NOTIF(GENERATOR_UNDERATTACK, N_ENABLE, 0, 0, "", CPID_Null, "0 0", _("^BGThe generator is under attack!"), "")
MULTITEAM_CENTER(ROUND_TEAM_LOSS, N_ENABLE, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG team loses the round"), "", NAME)
MULTITEAM_CENTER(ROUND_TEAM_WIN, N_ENABLE, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG team wins the round"), "", NAME)
+ MULTITEAM_CENTER(ROUND_TEAM_SCORES, N_ENABLE, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG scores"), "", NAME)
MSG_CENTER_NOTIF(ROUND_PLAYER_WIN, N_ENABLE, 1, 0, "s1", CPID_ROUND, "0 0", _("^BG%s^BG wins the round"), "")
MSG_CENTER_NOTIF(FREEZETAG_SELF, N_ENABLE, 0, 0, "", CPID_Null, "0 0", _("^K1You froze yourself"), "")
MSG_CENTER_NOTIF(MISSING_TEAMS, N_ENABLE, 0, 1, "missing_teams", CPID_MISSING_TEAMS, "-1 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "")
MSG_CENTER_NOTIF(MISSING_PLAYERS, N_ENABLE, 0, 1, "f1", CPID_MISSING_PLAYERS, "-1 0", _("^BGWaiting for %s player(s) to join..."), "")
+ MSG_CENTER_NOTIF(MISSING_READY, N_ENABLE, 0, 0, "", CPID_MISSING_READY, "-1 0", _("^BGThe match will begin\nwhen more players are ready.\n\nPress ^F2F4^BG to get ready"), "")
MSG_CENTER_NOTIF(INSTAGIB_DOWNGRADE, N_ENABLE, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "5 0", _("^BGYour weapon has been downgraded until you find some ammo!"), "")
MSG_CENTER_NOTIF(INSTAGIB_FINDAMMO, N_ENABLE, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "1 9", _("^F4^COUNT^BG left to find some ammo!"), "")
MSG_CENTER_NOTIF(TIMEOUT_BEGINNING, N_ENABLE, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout begins in ^COUNT"), "")
MSG_CENTER_NOTIF(TIMEOUT_ENDING, N_ENABLE, 0, 1, "", CPID_TIMEIN, "1 f1", _("^F4Timeout ends in ^COUNT"), "")
+ MSG_CENTER_NOTIF(TIMEOUT_ONGOING, N_ENABLE, 0, 0, "", CPID_TIMEIN, "1 f1", _("^F4Match paused"), "")
MSG_CENTER_NOTIF(JOIN_PREVENT_MINIGAME, N_ENABLE, 0, 0, "", CPID_Null, "0 0", _("^K1Cannot join given minigame session!"), "" )
#include <common/constants.qh>
#include <common/net_linked.qh>
#include <common/teams.qh>
- #include <server/autocvars.qh>
#include <server/command/getreplies.qh>
#include <server/mutators/_mod.qh>
#include <server/world.qh>
case MSG_CENTER:
case MSG_MULTI:
case MSG_CHOICE:
+ case MSG_MEDAL:
break;
default:
LOG_INFOF(
float channel,
string snd,
float vol,
- float position)
+ float position,
+ float queuetime)
{
// Set MSG_ANNCE information and handle precaching
#ifdef CSQC
notif.nent_snd = strzone(snd);
notif.nent_vol = vol;
notif.nent_position = position;
+ notif.nent_queuetime = queuetime;
}
}
else
}
}
+void Create_Notification_Entity_Medal(entity notif,
+ float var_cvar,
+ string namestring,
+ /* MSG_MEDAL */
+ string icon,
+ Notification anncename)
+ {
+ notif.nent_floatcount = 1;
+ if (icon != "") { notif.nent_icon = strzone(icon); }
+ if (anncename) { notif.nent_msgannce = anncename; }
+ }
// ===============
// Cvar Handling
int NOTIF_CENTER_COUNT = 0;
int NOTIF_MULTI_COUNT = 0;
int NOTIF_CHOICE_COUNT = 0;
+ int NOTIF_MEDAL_COUNT = 0;
FOREACH(Notifications, true, {
switch (it.nent_type)
{
case MSG_CENTER: ++NOTIF_CENTER_COUNT; break;
case MSG_MULTI: ++NOTIF_MULTI_COUNT; break;
case MSG_CHOICE: ++NOTIF_CHOICE_COUNT; break;
+ case MSG_MEDAL: ++NOTIF_MEDAL_COUNT; break;
}
});
"Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
);
});
+
+ NOTIF_WRITE(sprintf("\n// MSG_MEDAL notifications (count = %d):\n", NOTIF_MEDAL_COUNT));
+ FOREACH(Notifications, it.nent_type == MSG_MEDAL && (!it.nent_teamnum || it.nent_teamnum == NUM_TEAM_1), {
+ NOTIF_WRITE_ENTITY(it,
+ "Enable this multiple notification"
+ );
+ });
// edit these to match whichever cvars are used for specific notification options
NOTIF_WRITE("\n// HARD CODED notification variables:\n");
NOTIF_INFO_COUNT +
NOTIF_CENTER_COUNT +
NOTIF_MULTI_COUNT +
- NOTIF_CHOICE_COUNT
+ NOTIF_CHOICE_COUNT +
+ NOTIF_MEDAL_COUNT
),
NOTIF_ANNCE_COUNT,
NOTIF_INFO_COUNT,
NOTIF_CENTER_COUNT,
NOTIF_MULTI_COUNT,
- NOTIF_CHOICE_COUNT
+ NOTIF_CHOICE_COUNT,
+ NOTIF_MEDAL_COUNT
));
#undef NOTIF_WRITE_HARDCODED
#undef NOTIF_WRITE_ENTITY
#endif
centerprint_Add(ORDINAL(cpid), input, stof(arg_slot[0]), stof(arg_slot[1]));
}
+
+void Local_Notification_Queue_Run(MSG net_type, entity notif, float f1)
+{
+ switch (net_type)
+ {
+ case MSG_ANNCE:
+ {
+ Local_Notification_sound(notif.nent_channel, notif.nent_snd, notif.nent_vol, notif.nent_position);
+ break;
+ }
+
+ case MSG_MEDAL:
+ {
+ 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, float f1)
+{
+ //LOG_INFOF("Comparison %d > %d", time, notif_queue_next_time);
+ if(queue_time == -1 || time > notif_queue_next_time) {
+ //LOG_INFOF("Running NOW!");
+ 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);
+ if(notif_queue_length >= NOTIF_QUEUE_MAX) return;
+
+ 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;
+ }
+}
+
+void Local_Notification_Queue_Process()
+{
+ if(!notif_queue_length)
+ return;
+
+ int j;
+
+ 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], 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;
+ }
+}
+
#endif
void Local_Notification(MSG net_type, Notification net_name, ...count)
case MSG_ANNCE:
{
#ifdef CSQC
- Local_Notification_sound(notif.nent_channel, notif.nent_snd, notif.nent_vol, notif.nent_position);
+ //Local_Notification_sound(notif.nent_channel, notif.nent_snd, notif.nent_vol, notif.nent_position);
+ Local_Notification_Queue_Add(
+ net_type,
+ notif,
+ notif.nent_queuetime,
+ f1);
#else
backtrace("MSG_ANNCE on server?... Please notify Samual immediately!\n");
#endif
found_choice.nent_floatcount,
s1, s2, s3, s4,
f1, f2, f3, f4);
+ break;
}
+
+ #ifdef CSQC
+ case MSG_MEDAL:
+ {
+ Local_Notification_Queue_Add(
+ net_type,
+ notif,
+ MSG_MEDAL_TIME,
+ f1);
+ break;
+ }
+ #endif
}
}
#include <common/sounds/sound.qh>
#include <common/weapons/all.qh>
- #ifdef CSQC
- #include <client/autocvars.qh>
- #endif
-
// Operator for bold notifications
#define BOLD_OPERATOR "^BOLD"
CASE(MSG, CHOICE)
/** Kill centerprint message @deprecated */
CASE(MSG, CENTER_KILL)
+ /** Medal notification */
+ CASE(MSG, MEDAL)
ENUMCLASS_END(MSG)
string Get_Notif_TypeName(MSG net_type)
case MSG_CENTER: return "MSG_CENTER";
case MSG_MULTI: return "MSG_MULTI";
case MSG_CHOICE: return "MSG_CHOICE";
+ case MSG_MEDAL: return "MSG_MEDAL";
}
LOG_WARNF("Get_Notif_TypeName(%d): Improper net type!", ORDINAL(net_type));
return "";
CASE(CPID, LMS)
CASE(CPID, MISSING_TEAMS)
CASE(CPID, MISSING_PLAYERS)
+ CASE(CPID, MISSING_READY)
CASE(CPID, INSTAGIB_FINDAMMO)
CASE(CPID, CAMPAIGN_MESSAGE)
CASE(CPID, MOTD)
float channel,
string snd,
float vol,
- float position);
+ float position,
+ float queuetime);
void Create_Notification_Entity_InfoCenter(entity notif,
float var_cvar,
Notification optiona,
Notification optionb);
+void Create_Notification_Entity_Medal(entity notif,
+ float var_cvar,
+ string namestring,
+ /* MSG_MEDAL */
+ string icon,
+ Notification anncename);
+
void Dump_Notifications(int fh, bool alsoprint);
GENERIC_COMMAND(dumpnotifs, "Dump all notifications into notifications_dump.txt", false)
const float NOTIF_MAX_HUDARGS = 2;
const float NOTIF_MAX_DURCNT = 2;
+#ifdef CSQC
+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;
+
+void Local_Notification_Queue_Process();
+#endif
+
string arg_slot[NOTIF_MAX_ARGS];
const float ARG_CS_SV_HA = 1; // enabled on CSQC, SVQC, and Hudargs
ARG_CASE(ARG_CS, "join_key", getcommandkey(_("jump"), "+jump")) \
ARG_CASE(ARG_CS, "frag_ping", notif_arg_frag_ping(true, f2)) \
ARG_CASE(ARG_CS, "frag_stats", notif_arg_frag_stats(f2, f3, f4)) \
- /*ARG_CASE(ARG_CS, "frag_pos", ((Should_Print_Score_Pos(f1)) ? sprintf("\n^BG%s", Read_Score_Pos(f1)) : ""))*/ \
+ ARG_CASE(ARG_CS, "frag_pos", notif_arg_frag_pos(f2)) \
ARG_CASE(ARG_CS, "spree_cen", (autocvar_notification_show_sprees ? notif_arg_spree_cen(f1) : "")) \
ARG_CASE(ARG_CS_SV, "spree_inf", (autocvar_notification_show_sprees ? notif_arg_spree_inf(1, input, s2, f2) : "")) \
ARG_CASE(ARG_CS_SV, "spree_end", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \
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_pos(int score)
+{
+ entity pl;
+ int place = 1;
+ string str, color, tail;
+ bool tied = false;
+
+ for(pl = players.sort_next; pl; pl = pl.sort_next) {
+ if(pl.team == NUM_SPECTATOR) continue;
+ if(pl.(scores(SP_SCORE)) == score) break;
+ ++place;
+ }
+
+ entity prev = pl.sort_prev;
+ entity next = pl.sort_next;
+ if(prev && prev.(scores(SP_SCORE)) == score) {
+ tied = true;
+ --place; // We're tied always for the best place
+ }
+ if(next && next.(scores(SP_SCORE)) == score) {
+ tied = true;
+ }
+
+ switch(place) {
+ case 1:
+ color = "^4";
+ break;
+ case 2:
+ color = "^1";
+ break;
+ case 3:
+ color = "^3";
+ break;
+ default:
+ color = "";
+ }
+
+ switch(place % 10) {
+ case 1:
+ tail = "st";
+ break;
+ case 2:
+ tail = "nd";
+ break;
+ case 3:
+ tail = "rd";
+ break;
+ default:
+ tail = "th";
+ }
+
+ str = strcat(color, ftos(place), tail);
+ if(tied)
+ return strcat("Tied for ", str);
+ else
+ return str;
+}
+
string notif_arg_frag_ping(bool newline, float fping)
{
string s = newline ? "\n" : " ";
.string nent_snd;
.float nent_vol;
.float nent_position;
+.float nent_queuetime;
// MSG_INFO and MSG_CENTER entity values
.string nent_args; // used by both
return it;
}
-#define MSG_ANNCE_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position) \
- MSG_ANNCE_NOTIF_(teamnum, ANNCE_##name, ANNCE_##cvarname, defaultvalue, sound, channel, volume, position)
+#define MSG_ANNCE_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position, queuetime) \
+ MSG_ANNCE_NOTIF_(teamnum, ANNCE_##name, ANNCE_##cvarname, defaultvalue, sound, channel, volume, position, queuetime)
-#define MSG_ANNCE_NOTIF(name, defaultvalue, sound, channel, volume, position) \
+#define MSG_ANNCE_NOTIF(name, defaultvalue, sound, channel, volume, position, queuetime) \
NOTIF_ADD_AUTOCVAR(ANNCE_##name, defaultvalue) \
- MSG_ANNCE_NOTIF_(0, ANNCE_##name, ANNCE_##name, defaultvalue, sound, channel, volume, position)
+ MSG_ANNCE_NOTIF_(0, ANNCE_##name, ANNCE_##name, defaultvalue, sound, channel, volume, position, queuetime)
-#define MSG_ANNCE_NOTIF_(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position) \
+#define MSG_ANNCE_NOTIF_(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position, queuetime) \
REGISTER(Notifications, name, m_id, new_pure(msg_annce_notification)) { \
Create_Notification_Entity (this, defaultvalue, ACVNN(cvarname), MSG_ANNCE, strtoupper(#name), teamnum); \
Create_Notification_Entity_Annce(this, ACVNN(cvarname), strtoupper(#name), \
- channel, /* channel */ \
- sound, /* snd */ \
- volume, /* vol */ \
- position); /* position */ \
+ channel, /* channel */ \
+ sound, /* snd */ \
+ volume, /* vol */ \
+ position, /* position */ \
+ queuetime); /* queuetime */ \
}
#define MSG_INFO_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle) \
optiona, /* optiona */ \
optionb); /* optionb */ \
}
+
+#define MSG_MEDAL_NOTIF(name, defaultvalue, icon, anncename) \
+ NOTIF_ADD_AUTOCVAR(MEDAL_##name, defaultvalue) \
+ MSG_MEDAL_NOTIF_(0, MEDAL_##name, MEDAL_##name, defaultvalue, icon, anncename)
+
+#define MSG_MEDAL_NOTIF_(teamnum, name, cvarname, defaultvalue, icon, anncename) \
+ REGISTER(Notifications, name, m_id, new_pure(msg_medal_notification)) { \
+ Create_Notification_Entity (this, defaultvalue, ACVNN(cvarname), MSG_MEDAL, strtoupper(#name), teamnum); \
+ Create_Notification_Entity_Medal(this, ACVNN(cvarname), strtoupper(#name), \
+ icon, \
+ anncename); \
+ }
REGISTRY_BEGIN(Notifications)
{
#pragma once
+ // you're next
+
#ifdef SVQC
- #include <server/autocvars.qh>
#include <server/client.qh>
+ #include <server/main.qh>
+ #include <common/gamemodes/sv_rules.qh>
+ #include <common/mapobjects/teleporters.qh>
#include <common/mapobjects/trigger/secret.qh>
+ #include <common/mutators/mutator/doublejump/doublejump.qh>
+ #include <common/mutators/mutator/itemstime/itemstime.qh>
+ #include <common/physics/player.qh>
#endif
// Full list of all stat constants, included in a single location for easy reference
float game_stopped;
float game_starttime; //point in time when the countdown to game start is over
float round_starttime; //point in time when the countdown to round start is over
+float overtime_starttime; // z411 point in time where first overtime started
+
+float checkrules_overtimesadded; // z411 add
+float timeout_last;
+float timeout_total_time;
+bool game_timeout;
+
bool autocvar_g_allow_oldvortexbeam;
int autocvar_leadlimit;
+ // TODO: world.qh can't be included here due to circular includes!
+ #define autocvar_fraglimit cvar("fraglimit")
+ #define autocvar_fraglimit_override cvar("fraglimit_override")
+ #define autocvar_timelimit cvar("timelimit")
+ #define autocvar_timelimit_override cvar("timelimit_override")
#endif
REGISTER_STAT(WEAPONRATEFACTOR, float, W_WeaponRateFactor(this))
REGISTER_STAT(GAME_STOPPED, int, game_stopped)
+
+REGISTER_STAT(GAME_TIMEOUT, bool, game_timeout)
+REGISTER_STAT(TIMEOUT_LAST, float, timeout_last)
+
REGISTER_STAT(GAMESTARTTIME, float, game_starttime)
REGISTER_STAT(STRENGTH_FINISHED, float)
REGISTER_STAT(INVINCIBLE_FINISHED, float)
REGISTER_STAT(VEHICLESTAT_RELOAD2, int)
REGISTER_STAT(VEHICLESTAT_W2MODE, int)
REGISTER_STAT(NADE_TIMER, float)
-REGISTER_STAT(SECRETS_TOTAL, int, secrets_total)
-REGISTER_STAT(SECRETS_FOUND, int, secrets_found)
+//REGISTER_STAT(SECRETS_TOTAL, int, secrets_total)
+//REGISTER_STAT(SECRETS_FOUND, int, secrets_found)
REGISTER_STAT(RESPAWN_TIME, float)
REGISTER_STAT(ROUNDSTARTTIME, float, round_starttime)
-REGISTER_STAT(MONSTERS_TOTAL, int)
-REGISTER_STAT(MONSTERS_KILLED, int)
+REGISTER_STAT(OVERTIMESTARTTIME, float, overtime_starttime)
+REGISTER_STAT(OVERTIMESADDED, float, checkrules_overtimesadded)
+//REGISTER_STAT(MONSTERS_TOTAL, int)
+//REGISTER_STAT(MONSTERS_KILLED, int)
REGISTER_STAT(BUFFS, int)
REGISTER_STAT(NADE_BONUS, float)
REGISTER_STAT(NADE_BONUS_TYPE, int)
int autocvar_sv_gameplayfix_noairborncorpse = 1;
int autocvar_sv_gameplayfix_noairborncorpse_allowsuspendeditems = 1;
int autocvar_sv_gameplayfix_delayprojectiles = 0;
+ bool autocvar_sv_gameplayfix_upwardvelocityclearsongroundflag = true;
#endif
REGISTER_STAT(GAMEPLAYFIX_DOWNTRACEONGROUND, int, autocvar_sv_gameplayfix_downtracesupportsongroundflag)
REGISTER_STAT(GAMEPLAYFIX_EASIERWATERJUMP, int, autocvar_sv_gameplayfix_easierwaterjump)
REGISTER_STAT(MOVEVARS_JUMPSTEP, int, cvar("sv_jumpstep"))
REGISTER_STAT(NOSTEP, int, cvar("sv_nostep"))
+ #ifdef SVQC
+ float autocvar_sv_friction_on_land;
+ var float autocvar_sv_friction_slick = 0.5;
+ #endif
REGISTER_STAT(MOVEVARS_FRICTION, float)
REGISTER_STAT(MOVEVARS_FRICTION_SLICK, float, autocvar_sv_friction_slick)
REGISTER_STAT(MOVEVARS_FRICTION_ONLAND, float, autocvar_sv_friction_on_land)
REGISTER_STAT(DODGING_FROZEN, int, autocvar_sv_dodging_frozen)
REGISTER_STAT(DODGING_TIMEOUT, float)
+ #ifdef SVQC
+ float autocvar_g_jetpack_acceleration_side;
+ float autocvar_g_jetpack_acceleration_up;
+ float autocvar_g_jetpack_antigravity;
+ int autocvar_g_jetpack_fuel;
+ float autocvar_g_jetpack_maxspeed_side;
+ float autocvar_g_jetpack_maxspeed_up;
+ float autocvar_g_jetpack_reverse_thrust;
+ #endif
REGISTER_STAT(JETPACK_ACCEL_SIDE, float, autocvar_g_jetpack_acceleration_side)
REGISTER_STAT(JETPACK_ACCEL_UP, float, autocvar_g_jetpack_acceleration_up)
REGISTER_STAT(JETPACK_ANTIGRAVITY, float, autocvar_g_jetpack_antigravity)
REGISTER_STAT(DOM_PPS_YELLOW, float)
REGISTER_STAT(DOM_PPS_PINK, float)
+ #ifdef SVQC
+ float autocvar_g_teleport_maxspeed;
+ #endif
REGISTER_STAT(TELEPORT_MAXSPEED, float, autocvar_g_teleport_maxspeed)
REGISTER_STAT(TELEPORT_TELEFRAG_AVOID, int, autocvar_g_telefrags_avoid)
REGISTER_STAT(MOVEVARS_AIRCONTROL_POWER, float)
REGISTER_STAT(MOVEVARS_AIRCONTROL_BACKWARDS, bool)
REGISTER_STAT(MOVEVARS_AIRCONTROL_SIDEWARDS, bool)
- noref bool autocvar_sv_gameplayfix_nogravityonground = true;
+ #ifdef SVQC
+ float autocvar_sv_gameplayfix_q2airaccelerate = 1;
+ bool autocvar_sv_gameplayfix_nogravityonground = true;
+ bool autocvar_sv_gameplayfix_gravityunaffectedbyticrate = true;
+ #endif
REGISTER_STAT(MOVEFLAGS, int, MOVEFLAG_VALID
| (autocvar_sv_gameplayfix_q2airaccelerate ? MOVEFLAG_Q2AIRACCELERATE : 0)
| (autocvar_sv_gameplayfix_nogravityonground ? MOVEFLAG_NOGRAVITYONGROUND : 0)
REGISTER_STAT(WARMUP_TIMELIMIT, float, warmup_limit)
#ifdef SVQC
float autocvar_sv_wallfriction;
+ #define autocvar_sv_gravity cvar("sv_gravity")
+ float autocvar_sv_stepheight;
#endif
REGISTER_STAT(MOVEVARS_WALLFRICTION, int, autocvar_sv_wallfriction)
REGISTER_STAT(MOVEVARS_TICRATE, float, autocvar_sys_ticrate)
#include "physics.qh"
+ float autocvar_sv_spectator_speed_multiplier;
+ float autocvar_sv_spectator_speed_multiplier_min = 1;
+ float autocvar_sv_spectator_speed_multiplier_max = 5;
+
void sys_phys_fix(entity this, float dt)
{
WarpZone_PlayerPhysics_FixVAngle(this);
void sys_phys_pregame_hold(entity this)
{
if (!IS_PLAYER(this)) { return; }
- const bool allowed_to_move = (time >= game_starttime && !game_stopped);
+ // z411
+ //const bool allowed_to_move = (time >= game_starttime && !game_stopped);
+ const bool allowed_to_move = (!game_stopped && !game_timeout);
if (!allowed_to_move) {
this.velocity = '0 0 0';
set_movetype(this, MOVETYPE_NONE);
#pragma once
+ float autocvar_g_chat_flood_burst;
+ float autocvar_g_chat_flood_burst_team;
+ float autocvar_g_chat_flood_burst_tell;
+ float autocvar_g_chat_flood_lmax;
+ float autocvar_g_chat_flood_lmax_team;
+ float autocvar_g_chat_flood_lmax_tell;
+ bool autocvar_g_chat_flood_notify_flooder;
+ float autocvar_g_chat_flood_spl;
+ float autocvar_g_chat_flood_spl_team;
+ float autocvar_g_chat_flood_spl_tell;
+ int autocvar_g_chat_nospectators;
+ bool autocvar_g_chat_teamcolors;
+ bool autocvar_g_chat_tellprivacy;
+
++bool autocvar_sv_chat_sounds;
++float autocvar_sv_chat_sounds_flood;
++string autocvar_sv_chat_sounds_list;
++
const float NUM_NEAREST_ENTITIES = 4;
entity nearest_entity[NUM_NEAREST_ENTITIES];
float nearest_length[NUM_NEAREST_ENTITIES];
.float floodcontrol_chattell;
.float floodcontrol_voice;
.float floodcontrol_voiceteam;
+.float floodcontrol_chatsound;
#define CHAT_NOSPECTATORS() ((autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !warmup_stage))
int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodcontrol);
+bool play_chatsound(entity source, string msgin);
string NearestLocation(vector p);
#include <common/minigames/sv_minigames.qh>
#include <common/monsters/sv_monsters.qh>
#include <common/mutators/mutator/instagib/sv_instagib.qh>
+ #include <common/mutators/mutator/nades/nades.qh>
#include <common/mutators/mutator/overkill/oknex.qh>
#include <common/mutators/mutator/waypoints/all.qh>
#include <common/net_linked.qh>
#include <server/anticheat.qh>
#include <server/antilag.qh>
#include <server/bot/api.qh>
+ #include <server/bot/default/cvars.qh>
#include <server/campaign.qh>
#include <server/chat.qh>
#include <server/cheats.qh>
#include <server/weapons/common.qh>
#include <server/weapons/hitplot.qh>
#include <server/weapons/selection.qh>
+ #include <server/weapons/tracing.qh>
#include <server/weapons/weaponsystem.qh>
#include <server/world.qh>
WriteHeader(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
}
+void send_TeamNames(int channel, entity to) {
+ msg_entity = to;
+
+ WriteHeader(channel, TE_CSQC_TEAMNAMES);
+ WriteString(channel, autocvar_g_teamnames_red);
+ WriteString(channel, autocvar_g_teamnames_blue);
+ WriteString(channel, autocvar_g_teamnames_yellow);
+ WriteString(channel, autocvar_g_teamnames_pink);
+}
+
int CountSpectators(entity player, entity to)
{
if(!player) { return 0; } // not sure how, but best to be safe
setcolor(player, stof(autocvar_sv_defaultplayercolors));
}
+void ResetPlayerResources(entity this)
+{
+ if (warmup_stage) {
+ SetResource(this, RES_SHELLS, warmup_start_ammo_shells);
+ SetResource(this, RES_BULLETS, warmup_start_ammo_nails);
+ SetResource(this, RES_ROCKETS, warmup_start_ammo_rockets);
+ SetResource(this, RES_CELLS, warmup_start_ammo_cells);
+ SetResource(this, RES_PLASMA, warmup_start_ammo_plasma);
+ SetResource(this, RES_FUEL, warmup_start_ammo_fuel);
+ SetResource(this, RES_HEALTH, warmup_start_health);
+ SetResource(this, RES_ARMOR, warmup_start_armorvalue);
+ STAT(WEAPONS, this) = WARMUP_START_WEAPONS;
+ } else {
+ SetResource(this, RES_SHELLS, start_ammo_shells);
+ SetResource(this, RES_BULLETS, start_ammo_nails);
+ SetResource(this, RES_ROCKETS, start_ammo_rockets);
+ SetResource(this, RES_CELLS, start_ammo_cells);
+ SetResource(this, RES_PLASMA, start_ammo_plasma);
+ SetResource(this, RES_FUEL, start_ammo_fuel);
+ SetResource(this, RES_HEALTH, start_health);
+ SetResource(this, RES_ARMOR, start_armorvalue);
+ STAT(WEAPONS, this) = start_weapons;
+ if (MUTATOR_CALLHOOK(ForbidRandomStartWeapons, this) == false)
+ {
+ GiveRandomWeapons(this, random_start_weapons_count,
+ autocvar_g_random_start_weapons, random_start_ammo);
+ }
+ }
+}
+
void PutPlayerInServer(entity this)
{
if (this.vehicle) vehicles_exit(this.vehicle, VHEF_RELEASE);
this.takedamage = DAMAGE_AIM;
this.effects = EF_TELEPORT_BIT | EF_RESTARTANIM_BIT;
- if (warmup_stage) {
- SetResource(this, RES_SHELLS, warmup_start_ammo_shells);
- SetResource(this, RES_BULLETS, warmup_start_ammo_nails);
- SetResource(this, RES_ROCKETS, warmup_start_ammo_rockets);
- SetResource(this, RES_CELLS, warmup_start_ammo_cells);
- SetResource(this, RES_PLASMA, warmup_start_ammo_plasma);
- SetResource(this, RES_FUEL, warmup_start_ammo_fuel);
- SetResource(this, RES_HEALTH, warmup_start_health);
- SetResource(this, RES_ARMOR, warmup_start_armorvalue);
- STAT(WEAPONS, this) = WARMUP_START_WEAPONS;
- } else {
- SetResource(this, RES_SHELLS, start_ammo_shells);
- SetResource(this, RES_BULLETS, start_ammo_nails);
- SetResource(this, RES_ROCKETS, start_ammo_rockets);
- SetResource(this, RES_CELLS, start_ammo_cells);
- SetResource(this, RES_PLASMA, start_ammo_plasma);
- SetResource(this, RES_FUEL, start_ammo_fuel);
- SetResource(this, RES_HEALTH, start_health);
- SetResource(this, RES_ARMOR, start_armorvalue);
- STAT(WEAPONS, this) = start_weapons;
- if (MUTATOR_CALLHOOK(ForbidRandomStartWeapons, this) == false)
- {
- GiveRandomWeapons(this, random_start_weapons_count,
- autocvar_g_random_start_weapons, random_start_ammo);
- }
- }
+ ResetPlayerResources(this);
+
SetSpectatee_status(this, 0);
PS(this).dual_weapons = '0 0 0';
} else if (IS_PLAYER(this)) {
PutPlayerInServer(this);
}
+
+ // send team names
+ if(teamplay && IS_REAL_CLIENT(this))
+ send_TeamNames(MSG_ONE, this);
}
// TODO do we need all these fields, or should we stop autodetecting runtime
WriteByte(channel, this.cnt * 255.0); // g_balance_damagepush_speedfactor
WriteByte(channel, serverflags);
WriteCoord(channel, autocvar_g_trueaim_minrange);
+
+ // z411 send full hostname
+ WriteString(channel, (autocvar_hostname_full ? autocvar_hostname_full : autocvar_hostname));
}
void ClientInit_CheckUpdate(entity this)
modifications = strcat(modifications, ", Powerups");
modifications = substring(modifications, 2, strlen(modifications) - 2);
- string versionmessage = GetClientVersionMessage(this);
- string s = strcat(versionmessage, "^8\n^8\nhost is ^9", autocvar_hostname, "^8\n");
+ //string versionmessage = GetClientVersionMessage(this);
+ //string s = strcat(versionmessage, "^8\n^9", (autocvar_hostname_full ? autocvar_hostname_full : autocvar_hostname));
+ string s = (autocvar_hostname_full ? autocvar_hostname_full : autocvar_hostname);
- s = strcat(s, "^8\nmatch type is ^1", gamemode_name, "^8\n");
+ s = strcat(s, "^8\n^7", gamemode_name);
if(modifications != "")
- s = strcat(s, "^8\nactive modifications: ^3", modifications, "^8\n");
+ s = strcat(s, "^7 | ^3", modifications);
if(cache_lastmutatormsg != autocvar_g_mutatormsg)
{
}
if (cache_mutatormsg != "") {
- s = strcat(s, "\n\n^8special gameplay tips: ^7", cache_mutatormsg);
+ s = strcat(s, "\n^8tips: ^7", cache_mutatormsg);
}
string mutator_msg = "";
string motd = autocvar_sv_motd;
if (motd != "") {
- s = strcat(s, "\n\n^8MOTD: ^7", strreplace("\\n", "\n", motd));
+ s = strcat(s, "\n\n^7", strreplace("\\n", "\n", motd));
}
return s;
}
else
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_JOIN_PLAY, this.netname);
this.team_selected = false;
+
+ // z411
+ // send constant ready notification
+ if(warmup_stage)
+ Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MISSING_READY);
}
int GetPlayerLimit()
return false;
}
- if (timeout_status == TIMEOUT_ACTIVE) {
- // don't allow the player to turn around while game is paused
+ if (game_timeout) {
+ // don't allow the player to turn around while game is paused
// FIXME turn this into CSQC stuff
this.v_angle = this.lastV_angle;
this.angles = this.lastV_angle;
this.fixangle = true;
+ return false;
}
if (frametime) player_powerups(this);
#include <common/replicate.qh>
#include <common/sounds/all.qh>
+ bool autocvar__notarget;
+ int autocvar_g_balance_armor_start;
+ float autocvar_g_balance_pause_armor_rot_spawn;
+ float autocvar_g_balance_pause_fuel_rot_spawn;
+ float autocvar_g_balance_pause_health_regen_spawn;
+ float autocvar_g_balance_pause_health_rot_spawn;
+ bool autocvar_g_botclip_collisions;
+ bool autocvar_g_fullbrightplayers;
+ bool autocvar_g_playerclip_collisions;
+ float autocvar_g_player_alpha;
+ float autocvar_g_player_brightness;
+ float autocvar_g_player_damageforcescale = 2;
+ float autocvar_g_respawn_delay_small;
+ int autocvar_g_respawn_delay_small_count;
+ float autocvar_g_respawn_delay_large;
+ int autocvar_g_respawn_delay_large_count;
+ float autocvar_g_respawn_delay_max;
+ bool autocvar_g_respawn_delay_forced;
+ bool autocvar_g_respawn_ghosts;
+ float autocvar_g_respawn_ghosts_alpha = 1;
+ float autocvar_g_respawn_ghosts_fadetime = 1.5;
+ float autocvar_g_respawn_ghosts_time = 4.5;
+ float autocvar_g_respawn_ghosts_speed;
+ int autocvar_g_respawn_waves;
+ bool autocvar_g_nodepthtestplayers;
+ string autocvar_g_mutatormsg;
+ float autocvar_sv_foginterval;
+ float autocvar_sv_maxidle;
+ bool autocvar_sv_maxidle_spectatorsareidle;
+ int autocvar_sv_maxidle_slots;
+ bool autocvar_sv_maxidle_slots_countbots;
+ bool autocvar_g_forced_respawn;
+ int autocvar_g_maxplayers;
+ float autocvar_g_maxplayers_spectator_blocktime;
+ string autocvar_g_xonoticversion;
+ float autocvar_gameversion;
+ float autocvar_gameversion_min;
+ float autocvar_gameversion_max;
+ string autocvar_hostname;
+ int autocvar_spawn_debug;
+ string autocvar_sv_motd;
+ int autocvar_sv_name_maxlength = 64;
+ bool autocvar_sv_servermodelsonly;
+ int autocvar_sv_spectate;
+ bool autocvar_sv_teamnagger;
+ float autocvar_sv_player_scale;
+ bool autocvar_sv_showspectators;
+
++// z411
++string autocvar_hostname_full;
++string autocvar_g_teamnames_red;
++string autocvar_g_teamnames_blue;
++string autocvar_g_teamnames_yellow;
++string autocvar_g_teamnames_pink;
++
// WEAPONTODO
.string weaponorder_byimpulse;
ATTRIB(Client, colormap, int, this.colormap);
ATTRIB(Client, team, int, this.team);
ATTRIB(Client, clientcolors, int, this.clientcolors);
+ ATTRIB(Client, countrycode, int, this.countrycode);
/** Client IP */
ATTRIB(Client, netaddress, string, this.netaddress);
ATTRIB(Client, playermodel, string, this.playermodel);
ATTRIB(Client, cvar_cl_pokenade_type, string, this.cvar_cl_pokenade_type);
ATTRIB(Client, cvar_cl_spawn_near_teammate, bool, this.cvar_cl_spawn_near_teammate);
ATTRIB(Client, cvar_cl_gunalign, int, this.cvar_cl_gunalign);
+ ATTRIB(Client, cvar_cl_chat_sounds, bool, this.cvar_cl_chat_sounds);
ATTRIB(Client, cvar_cl_handicap, float, this.cvar_cl_handicap);
ATTRIB(Client, cvar_cl_clippedspectating, bool, this.cvar_cl_clippedspectating);
ATTRIB(Client, cvar_cl_autoscreenshot, int, this.cvar_cl_autoscreenshot);
#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 countrycode;
.int killcount;
//flood fields
#define SPECTATE_COPYFIELD(fld) SPECTATE_COPY() { this.(fld) = spectatee.(fld); }
const int MAX_SPECTATORS = 7;
+
+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);
#include <common/vehicles/all.qh>
#include <lib/warpzone/common.qh>
#include <server/bot/api.qh>
+ #include <server/bot/default/waypoints.qh>
#include <server/campaign.qh>
#include <server/chat.qh>
#include <server/cheats.qh>
{
case CMD_REQUEST_COMMAND:
{
- if (!game_stopped && IS_CLIENT(caller) && !IS_PLAYER(caller))
+ if (!game_stopped && !game_timeout && IS_CLIENT(caller) && !IS_PLAYER(caller))
{
if (joinAllowed(caller))
Join(caller);
}
}
-void ClientCommand_ready(entity caller, int request) // todo: anti-spam for toggling readyness
+void ClientCommand_ready(entity caller, int request)
{
switch (request)
{
case CMD_REQUEST_COMMAND:
{
- if (IS_CLIENT(caller))
+ if (IS_CLIENT(caller) && caller.last_ready < time - 3) // anti-spam
{
if (warmup_stage || autocvar_sv_ready_restart || g_race_qualifying == 2)
{
{
caller.ready = false;
if(IS_PLAYER(caller) || caller.caplayer == 1)
- bprint(playername(caller.netname, caller.team, false), "^2 is ^1NOT^2 ready\n");
+ bprint("\{1}", playername(caller.netname, caller.team, false), "^2 is ^1NOT^2 ready\n");
}
else
{
caller.ready = true;
if(IS_PLAYER(caller) || caller.caplayer == 1)
- bprint(playername(caller.netname, caller.team, false), "^2 is ready\n");
+ bprint("\{1}", playername(caller.netname, caller.team, false), "^2 is ready\n");
}
+
+ caller.last_ready = time;
// cannot reset the game while a timeout is active!
if (!timeout_status) ReadyCount();
{
case CMD_REQUEST_COMMAND:
{
- if (!intermission_running && IS_CLIENT(caller))
+ if (!intermission_running && IS_CLIENT(caller) && !game_timeout)
{
if(argv(1) != "")
{
}
}
+void ClientCommand_sounds(entity caller, int request)
+{
+ switch (request)
+ {
+ case CMD_REQUEST_COMMAND:
+ {
+ sprint(caller, strcat("Available sounds: \n\n", autocvar_sv_chat_sounds_list, "\n"));
+ return; // never fall through to usage
+ }
+
+ default:
+ case CMD_REQUEST_USAGE:
+ {
+ sprint(caller, "\nUsage:^3 cmd sounds\n");
+ return;
+ }
+ }
+}
+
void ClientCommand_suggestmap(entity caller, int request, int argc)
{
switch (request)
CLIENT_COMMAND("selfstuff", ClientCommand_selfstuff(ent, request, command), "Stuffcmd a command to your own client") \
CLIENT_COMMAND("sentcvar", ClientCommand_sentcvar(ent, request, arguments, command), "New system for sending a client cvar to the server") \
CLIENT_COMMAND("spectate", ClientCommand_spectate(ent, request), "Become an observer") \
+ CLIENT_COMMAND("sounds", ClientCommand_sounds(ent, request), "Get list of commsnds") \
CLIENT_COMMAND("suggestmap", ClientCommand_suggestmap(ent, request, arguments), "Suggest a map to the mapvote at match end") \
CLIENT_COMMAND("tell", ClientCommand_tell(ent, request, arguments, command), "Send a message directly to a player") \
CLIENT_COMMAND("voice", ClientCommand_voice(ent, request, arguments, command), "Send voice message via sound") \
#include <common/vehicles/all.qh>
#include <common/weapons/_all.qh>
#include <lib/warpzone/common.qh>
+ #include <server/campaign.qh>
#include <server/chat.qh>
#include <server/client.qh>
#include <server/command/common.qh>
if (timeout_time == autocvar_sv_timeout_resumetime) // play a warning sound when only <sv_timeout_resumetime> seconds are left
Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_PREPARE);
- this.nextthink = time + TIMEOUT_SLOWMO_VALUE; // think again in one second
+ //this.nextthink = time + TIMEOUT_SLOWMO_VALUE; // think again in one second
+ this.nextthink = time + 1;
timeout_time -= 1; // decrease the time counter
}
+ else if (timeout_time == -1) // infinite timer
+ {
+ Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_TIMEOUT_ONGOING);
+ this.nextthink = time + TIMEOUT_SLOWMO_VALUE;
+ }
else // time to end the timeout
{
Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_TIMEIN);
timeout_status = TIMEOUT_INACTIVE;
+ float total_time = time - timeout_last;
// reset the slowmo value back to normal
- cvar_set("slowmo", ftos(orig_slowmo));
+ // z411 TODO
+ //cvar_set("slowmo", ftos(orig_slowmo));
+
+ // Disable timeout and fix times
+ game_timeout = false;
+ timeout_total_time += total_time;
+ game_starttime += total_time;
+ if(round_handler && round_handler_GetEndTime() > 0)
+ round_handler.round_endtime += total_time;
+
+ LOG_INFOF("Timeout lasted %d secs", total_time);
// unlock the view for players so they can move around again
FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), {
timeout_status = TIMEOUT_ACTIVE;
// set the slowmo value to the timeout default slowmo value
- cvar_set("slowmo", ftos(TIMEOUT_SLOWMO_VALUE));
+ //cvar_set("slowmo", ftos(TIMEOUT_SLOWMO_VALUE));
+ game_timeout = true;
+ timeout_last = time;
+
+ // play timeout sound
+ sound(NULL, CH_INFO, SND_TIMEOUT, VOL_BASE, ATTN_NONE);
// reset all the flood variables
FOREACH_CLIENT(true, {
{
timeout_time = autocvar_sv_timeout_resumetime;
timeout_handler.nextthink = time; // timeout_handler has to take care of it immediately
- bprint(strcat("^1Attention: ^7", GetCallerName(caller), " resumed the game! Prepare for battle!\n"));
+ bprint(strcat("\{1}^1Attention: ^7", GetCallerName(caller), " resumed the game! Prepare for battle!\n"));
return;
}
{
if (caller) CS(caller).allowed_timeouts -= 1;
// write a bprint who started the timeout (and how many they have left)
- bprint(GetCallerName(caller), " ^7called a timeout", (caller ? strcat(" (", ftos(CS(caller).allowed_timeouts), " timeout(s) left)") : ""), "!\n");
+ bprint("\{1}", GetCallerName(caller), " ^7called a timeout", (caller ? strcat(" (", ftos(CS(caller).allowed_timeouts), " timeout(s) left)") : ""), "!\n");
timeout_status = TIMEOUT_LEADTIME;
timeout_caller = caller;
timeout_handler = new(timeout_handler);
setthink(timeout_handler, timeout_handler_think);
timeout_handler.nextthink = time; // always let the entity think asap
-
+
Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_TIMEOUT);
}
}
#include <common/util.qh>
#include <common/weapons/_all.qh>
#include <server/client.qh>
+ #include <server/command/banning.qh>
#include <server/command/common.qh>
#include <server/command/vote.qh>
#include <server/damage.qh>
// add up all the votes from each connected client
FOREACH_CLIENT(IS_REAL_CLIENT(it) && IS_CLIENT(it), {
+ // z411
+ if(vote_target_type == VOTE_TARGET_TEAM && it.team != vote_caller.team) continue;
+ if(vote_target_type == VOTE_TARGET_SINGLE && it != vote_target) continue;
+
++vote_player_count;
if (IS_PLAYER(it)) ++vote_real_player_count;
switch (it.vote_selection)
restart_mapalreadyrestarted = true;
reset_map(true);
Score_ClearAll();
+ Inventory_ClearAll();
delete(this);
}
warmup_stage = 0; // once the game is restarted the game is in match stage
// reset the .ready status of all players (also spectators)
- FOREACH_CLIENT(IS_REAL_CLIENT(it), { it.ready = false; });
+ FOREACH_CLIENT(IS_REAL_CLIENT(it), {
+ it.ready = false;
+ Kill_Notification(NOTIF_ONE_ONLY, it, MSG_CENTER, CPID_MISSING_READY);
+ });
readycount = 0;
Nagger_ReadyCounted(); // NOTE: this causes a resend of that entity, and will also turn off warmup state on the client
FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { CS(it).allowed_timeouts = autocvar_sv_timeout_number; });
}
+ round_handler_Activate(true);
if (!sv_ready_restart_after_countdown) reset_map(true);
if (autocvar_sv_eventlog) GameLogEcho(":restart");
}
// Reset ALL scores, but only do that at the beginning of the countdown if sv_ready_restart_after_countdown is off!
// Otherwise scores could be manipulated during the countdown.
- if (!sv_ready_restart_after_countdown) Score_ClearAll();
+ if (!sv_ready_restart_after_countdown) {
+ Score_ClearAll();
+ Inventory_ClearAll();
+ }
ReadyRestart_force();
}
case MUT_VOTEPARSE_UNACCEPTABLE: { return 0; }
}
+ vote_target_type = VOTE_TARGET_ALL;
+
switch (first_command) // now go through and parse the proper commands to adjust as needed.
{
case "kick":
if (first_command == "kickban")
command_arguments = strcat(ftos(autocvar_g_ban_default_bantime), " ", ftos(autocvar_g_ban_default_masksize), " ~");
- vote_parsed_command = strcat(first_command, " # ", ftos(etof(victim)), " ", command_arguments);
+ vote_parsed_command = strcat("defer 2 ", first_command, " # ", ftos(etof(victim)), " ", command_arguments);
vote_parsed_display = sprintf("^1%s #%d ^7%s^1 %s", first_command, etof(victim), victim.netname, reason);
}
else { print_to(caller, strcat("vcall: ", GetClientErrorString(accepted, argv(startpos + 1)), ".\n")); return 0; }
{
vote_command = ValidateMap(argv(startpos + 1), caller);
if (!vote_command) return -1;
- vote_parsed_command = strcat("gotomap ", vote_command);
+ vote_parsed_command = strcat("defer 2 gotomap ", vote_command);
vote_parsed_display = strzone(strcat("^1", vote_parsed_command));
break;
}
+
+ // z411 team calls
+ case "teamname":
+ {
+ if (teamplay && Team_IsValidTeam(caller.team)) {
+ vote_target_type = VOTE_TARGET_TEAM;
+
+ string tmname = strtolower(Static_Team_ColorName(caller.team));
+ string newname = argv(startpos + 1);
+
+ vote_parsed_command = strcat(first_command, " ", tmname, " \"", newname, "\"");
+ vote_parsed_display = strzone(strcat("^3(Team) ^1", first_command, " ^2", newname));
+ } else { print_to(caller, "vcall: Not in a team\n"); return 0; }
+
+ break;
+ }
// TODO: replicate the old behaviour of being able to vote for maps from different modes on multimode servers (possibly support it in gotomap too)
// maybe fallback instead of aborting if map name is invalid?
}
case "restart":
+ case "shuffleteams":
+ case "allready":
+ case "endmatch":
{
// add a delay so that vote result can be seen and announcer can be heard
// if the vote is accepted
- vote_parsed_command = strcat("defer 1 ", vote_command);
+ vote_parsed_command = strcat("defer 2 ", vote_command);
vote_parsed_display = strzone(strcat("^1", vote_command));
break;
#pragma once
- // ================================================
- // Declarations for the vote system/vote commands
- // Last updated: December 14th, 2011
- // ================================================
+ bool autocvar_sv_vote_call;
+ bool autocvar_sv_vote_change;
+ string autocvar_sv_vote_commands;
+ int autocvar_sv_vote_limit;
+ float autocvar_sv_vote_majority_factor;
+ float autocvar_sv_vote_majority_factor_of_voted;
+ bool autocvar_sv_vote_master;
+ bool autocvar_sv_vote_master_callable;
+ string autocvar_sv_vote_master_commands;
+ string autocvar_sv_vote_master_password;
+ int autocvar_sv_vote_master_playerlimit;
+ bool autocvar_sv_vote_no_stops_vote;
+ int autocvar_sv_vote_nospectators;
+ //string autocvar_sv_vote_only_commands;
+ bool autocvar_sv_vote_override_mostrecent;
+ bool autocvar_sv_vote_singlecount;
+ float autocvar_sv_vote_stop;
+ float autocvar_sv_vote_timeout;
+ float autocvar_sv_vote_wait;
+ bool autocvar_sv_vote_gamestart;
// definitions for command selection between progs
const float VC_ASGNMNT_BOTH = 1;
const float VOTE_NORMAL = 1;
const float VOTE_MASTER = 2;
+// z411 vote targets
+const float VOTE_TARGET_ALL = 0;
+const float VOTE_TARGET_TEAM = 1;
+const float VOTE_TARGET_SINGLE = 2;
+
// global vote information declarations
entity vote_caller; // original caller of the current vote
string vote_caller_name; // name of the vote caller
float vote_reject_count; // same as above, but rejected
float vote_abstain_count; // same as above, but abstained
float vote_needed_overall; // total amount of players NEEDED for a vote to pass (based on sv_vote_majority_factor)
+float vote_target_type; // z411
+entity vote_target; // z411
.float vote_master; // flag for if the player has vote master privelages
.float vote_waittime; // flag for how long the player must wait before they can vote again
.float vote_selection; // flag for which vote selection the player has made (See VOTE_SELECT_*)
float readyrestart_happened; // keeps track of whether a restart has already happened
float restart_mapalreadyrestarted; // bool, indicates whether reset_map() was already executed
.float ready; // flag for if a player is ready
+.float last_ready; // z411 time of the last readyup for anti-spam
.int team_saved; // team number to restore upon map reset
.void(entity this) reset; // if set, an entity is reset using this
.void(entity this) reset2; // if set, an entity is reset using this (after calling ALL the reset functions for other entities)
#include <server/weapons/accuracy.qh>
#include <server/weapons/csqcprojectile.qh>
#include <server/weapons/selection.qh>
+ #include <server/weapons/weaponsystem.qh>
#include <server/world.qh>
void UpdateFrags(entity player, int f)
float Obituary_WeaponDeath(
entity notif_target,
+ entity attacker,
float murder,
int deathtype,
string s1, string s2, string s3,
s1, s2, s3, "",
f1, f2, 0, 0
);
+
+ // z411 special medals
+ if(attacker) {
+ switch(death_message) {
+ case WEAPON_SHOTGUN_MURDER_SLAP:
+ if(!cvar("g_melee_only")) { // don't spam humiliation if we're in melee_only mode
+ Give_Medal(attacker, HUMILIATION);
+ }
+ break;
+ case WEAPON_ELECTRO_MURDER_COMBO:
+ Give_Medal(attacker, ELECTROBITCH);
+ break;
+ }
+ }
}
else
{
notif_anonymous = M_ARGV(5, bool);
if(notif_anonymous)
- attacker_name = "Anonymous player";
+ attacker_name = "???";
#ifdef NOTIFICATIONS_DEBUG
Debug_Notification(
}
}
}
- else if (!Obituary_WeaponDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0))
+ else if (!Obituary_WeaponDeath(targ, NULL, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0))
{
backtrace("SUICIDE: what the hell happened here?\n");
return;
}
LogDeath("suicide", deathtype, targ, targ);
+ Send_Notification(NOTIF_ONE, targ, MSG_ANNCE, ANNCE_SUICIDE);
if(deathtype != DEATH_AUTOTEAMCHANGE.m_id) // special case: don't negate frags if auto switched
GiveFrags(attacker, targ, -1, deathtype, weaponentity);
}
Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAG, targ.netname);
Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAGGED, attacker_name);
- Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(targ.team, INFO_DEATH_TEAMKILL), targ.netname, attacker_name, deathlocation, CS(targ).killcount);
+ Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(targ.team, INFO_DEATH_TEAMKILL),
+ playername(targ.netname, targ.team, true), playername(attacker_name, attacker.team, true),
+ deathlocation, CS(targ).killcount);
// In this case, the death message will ALWAYS be "foo was betrayed by bar"
// No need for specific death/weapon messages...
CS(attacker).killcount = CS(attacker).killcount + 1;
attacker.killsound += 1;
-
+
// TODO: improve SPREE_ITEM and KILL_SPREE_LIST
// these 2 macros are spread over multiple files
#define SPREE_ITEM(counta,countb,center,normal,gentle) \
case counta: \
- Send_Notification(NOTIF_ONE, attacker, MSG_ANNCE, ANNCE_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
+ 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)
{
if(deathtype == DEATH_BUFF.m_id)
f3 = buff_FirstFromFlags(STAT(BUFFS, attacker)).m_id;
- if (!Obituary_WeaponDeath(targ, true, deathtype, targ.netname, attacker_name, deathlocation, CS(targ).killcount, kill_count_to_attacker))
- Obituary_SpecialDeath(targ, true, deathtype, targ.netname, attacker_name, deathlocation, CS(targ).killcount, kill_count_to_attacker, f3);
+ if (!Obituary_WeaponDeath(targ, attacker, true, deathtype, playername(targ.netname, targ.team, true), playername(attacker_name, attacker.team, true), deathlocation, CS(targ).killcount, kill_count_to_attacker))
+ Obituary_SpecialDeath(targ, true, deathtype, playername(targ.netname, targ.team, true), playername(attacker_name, attacker.team, true), deathlocation, CS(targ).killcount, kill_count_to_attacker, f3);
}
}
case DEATH_HURTTRIGGER:
{
Obituary_SpecialDeath(targ, false, deathtype,
- targ.netname,
+ playername(targ.netname, targ.team, true),
inflictor.message,
deathlocation,
CS(targ).killcount,
case DEATH_CUSTOM:
{
Obituary_SpecialDeath(targ, false, deathtype,
- targ.netname,
+ playername(targ.netname, targ.team, true),
((strstrofs(deathmessage, "%", 0) < 0) ? strcat("%s ", deathmessage) : deathmessage),
deathlocation,
CS(targ).killcount,
default:
{
- Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
+ Obituary_SpecialDeath(targ, false, deathtype, playername(targ.netname, targ.team, true), deathlocation, "", CS(targ).killcount, 0, 0);
break;
}
}
LogDeath("accident", deathtype, targ, targ);
+ Send_Notification(NOTIF_ONE, targ, MSG_ANNCE, ANNCE_ACCIDENT);
GiveFrags(targ, targ, -1, deathtype, weaponentity);
if(GameRules_scoring_add(targ, SCORE, 0) == -5)
damage = 0;
force = '0 0 0';
}
- else if(SAME_TEAM(attacker, targ))
+ else if(!STAT(FROZEN, targ) && SAME_TEAM(attacker, targ))
{
if(autocvar_teamplay_mode == 1)
damage = 0;
if(IS_PLAYER(victim) || (IS_TURRET(victim) && victim.active == ACTIVE_ACTIVE) || IS_MONSTER(victim) || MUTATOR_CALLHOOK(PlayHitsound, victim, attacker))
{
- if(DIFF_TEAM(victim, attacker) && !STAT(FROZEN, victim))
+ if (DIFF_TEAM(victim, attacker))
{
if(damage > 0)
{
}
}
}
- else if(IS_PLAYER(attacker))
+ else if (IS_PLAYER(attacker) && !STAT(FROZEN, victim)) // same team
{
- // if enemy gets frozen in this frame and receives other damage don't
- // play the typehitsound e.g. when hit by multiple bullets of the shotgun
- if (deathtype != DEATH_FIRE.m_id && (!STAT(FROZEN, victim) || time > victim.freeze_time))
+ if (deathtype != DEATH_FIRE.m_id)
{
attacker.typehitsound += 1;
}
#include <common/weapons/_all.qh>
+ bool autocvar_g_throughfloor_debug;
+ float autocvar_g_throughfloor_damage;
+ float autocvar_g_throughfloor_force;
+ float autocvar_g_throughfloor_damage_max_stddev;
+ float autocvar_g_throughfloor_force_max_stddev;
+ float autocvar_g_throughfloor_min_steps_player;
+ float autocvar_g_throughfloor_max_steps_player;
+ float autocvar_g_throughfloor_min_steps_other;
+ float autocvar_g_throughfloor_max_steps_other;
+ float autocvar_g_mirrordamage;
+ bool autocvar_g_mirrordamage_virtual;
+ bool autocvar_g_mirrordamage_onlyweapons;
+ float autocvar_g_maxpushtime;
+ float autocvar_g_balance_damagepush_speedfactor;
+ int autocvar_g_balance_firetransfer_damage;
+ int autocvar_g_balance_firetransfer_time;
+ float autocvar_g_balance_armor_blockpercent;
+ float autocvar_g_teamdamage_resetspeed;
+ float autocvar_g_teamdamage_threshold;
+ float autocvar_g_balance_selfdamagepercent;
+ float autocvar_g_friendlyfire;
+ float autocvar_g_friendlyfire_virtual;
+ float autocvar_g_friendlyfire_virtual_force;
+ float autocvar_g_frozen_revive_falldamage;
+ int autocvar_g_frozen_revive_falldamage_health;
+ bool autocvar_g_frozen_damage_trigger;
+ float autocvar_g_frozen_force;
+
.void(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force) event_damage;
.bool(entity targ, entity inflictor, float amount, float limit) event_heal;
.float spawnshieldtime;
.int totalfrags;
+.float lastkill;
.bool canteamdamage;
float w_deathtype;
float Obituary_WeaponDeath(
entity notif_target,
+ entity target,
float murder,
int deathtype,
string s1, string s2, string s3,
#include <common/constants.qh>
#include <common/deathtypes/all.qh>
+ #include <common/gamemodes/gamemode/cts/cts.qh>
#include <common/items/_mod.qh>
#include <common/mapobjects/subs.qh>
#include <common/mapobjects/triggers.qh>
void Item_RespawnCountdown(entity this)
{
+ if(game_timeout) { this.nextthink = time + 1; return; }
+
if(this.item_respawncounter >= ITEM_RESPAWN_TICKS)
{
if(this.waypointsprite_attached)
else
{
this.nextthink = time + 1;
- this.item_respawncounter += 1;
+ this.item_respawncounter = floor((time - game_starttime) - (this.scheduledrespawntime - ITEM_RESPAWN_TICKS)) + 1;
+ //this.item_respawncounter += 1;
+ //LOG_INFOF("Respawncounter: %d", this.item_respawncounter);
+ if(this.item_respawncounter < 1) return;
+
if(this.item_respawncounter == 1)
{
do {
void Item_RespawnThink(entity this)
{
- this.nextthink = time;
+ this.nextthink = time + 1;
if(this.origin != this.oldorigin)
ItemUpdate(this);
-
- if(time >= this.wait)
+
+ if(!game_timeout && time - game_starttime >= this.wait)
Item_Respawn(this);
+
+ //LOG_INFOF("time until respawn %d", (this.wait) - (time - game_starttime));
}
void Item_ScheduleRespawnIn(entity e, float t)
if ((Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS) || MUTATOR_CALLHOOK(Item_ScheduleRespawn, e, t)) && (t - ITEM_RESPAWN_TICKS) > 0)
{
setthink(e, Item_RespawnCountdown);
- e.nextthink = time + max(0, t - ITEM_RESPAWN_TICKS);
- e.scheduledrespawntime = e.nextthink + ITEM_RESPAWN_TICKS;
+ //e.nextthink = time - timeout_total_time + max(0, t - ITEM_RESPAWN_TICKS);
+ //e.scheduledrespawntime = e.nextthink + ITEM_RESPAWN_TICKS;
+ e.nextthink = time;
+ e.scheduledrespawntime = time - game_starttime + t;
e.item_respawncounter = 0;
+
if(Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
{
t = Item_ItemsTime_UpdateTime(e, e.scheduledrespawntime);
{
setthink(e, Item_RespawnThink);
e.nextthink = time;
- e.scheduledrespawntime = time + t;
- e.wait = time + t;
+ e.scheduledrespawntime = time - game_starttime + t;
+ e.wait = time - game_starttime + t;
if(Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
{
return true;
}
+void Item_NotifyWeapon(entity player, int wep)
+{
+ if(IS_REAL_CLIENT(player)) {
+ msg_entity = player;
+ WriteHeader(MSG_ONE, TE_CSQC_WEAPONPICKUP);
+ WriteByte(MSG_ONE, wep);
+ }
+}
+
bool Item_GiveTo(entity item, entity player)
{
// if nothing happens to player, just return without taking the item
pickedup |= Item_GiveAmmoTo(item, player, RES_FUEL, g_pickup_fuel_max);
if (item.itemdef.instanceOfWeaponPickup)
{
- WepSet w;
+ WepSet w, wp;
w = STAT(WEAPONS, item);
- w &= ~STAT(WEAPONS, player);
+ wp = w & ~STAT(WEAPONS, player);
if (w || (item.spawnshieldtime && item.pickup_anyway > 0))
{
pickedup = true;
FOREACH(Weapons, it != WEP_Null, {
- if(w & (it.m_wepset))
+ Weapon wep = it;
+
+ if(w & (wep.m_wepset)) {
+ // z411 Seriously find a better way to do this
+ Item_NotifyWeapon(player, wep.m_id);
+ FOREACH_CLIENT(IS_SPEC(it) && it.enemy == player, { Item_NotifyWeapon(it, wep.m_id); });
+ }
+
+ if(wp & (wep.m_wepset))
{
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
.entity weaponentity = weaponentities[slot];
if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
- W_DropEvent(wr_pickup, player, it.m_id, item, weaponentity);
+ W_DropEvent(wr_pickup, player, wep.m_id, item, weaponentity);
}
- W_GiveWeapon(player, it.m_id);
+ W_GiveWeapon(player, wep.m_id);
}
});
}
#include <common/scores.qh>
+ bool autocvar_g_full_getstatus_responses;
+
entity scores_initialized; // non-NULL when scores labels/rules have been set
.float scoreboard_pos;
float WinningConditionHelper_equality; ///< we have no winner
entity WinningConditionHelper_winner; ///< the winning player, or NULL if none
entity WinningConditionHelper_second; ///< the second player, or NULL if none
+entity WinningConditionHelper_winner_last;
+entity WinningConditionHelper_equality_one;
+entity WinningConditionHelper_equality_two;
float WinningConditionHelper_lowerisbetter; ///< lower is better, duh
float WinningConditionHelper_zeroisworst; ///< zero is worst, duh
#define WINNINGCONDITIONHELPER_LOWERISBETTER_WORST 999999999
#include <common/gamemodes/_mod.qh>
#include <common/teams.qh>
#include <server/bot/api.qh>
+ #include <server/bot/default/cvars.qh>
+ #include <server/campaign.qh>
#include <server/client.qh>
#include <server/command/vote.qh>
#include <server/damage.qh>
.int m_team_balance_state; ///< Holds the state of the team balance entity.
.entity m_team_balance_team[NUM_TEAMS]; ///< ???
+.string m_team_name; // z411 team name
.float m_team_score; ///< The score of the team.
.int m_num_players; ///< Number of players (both humans and bots) in a team.
.int m_num_bots; ///< Number of bots in a team.
return g_team_entities[Team_TeamToIndex(team_num) - 1];
}
+string Team_GetTeamName(entity team_ent)
+{
+ return team_ent.m_team_name;
+}
+
+void Team_SetTeamName(entity team_ent, string name)
+{
+ team_ent.m_team_name = name;
+}
+
float Team_GetTeamScore(entity team_ent)
{
return team_ent.m_team_score;
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;
bool autocvar_g_balance_teams;
bool autocvar_g_balance_teams_prevent_imbalance;
+ string autocvar_g_forced_team_otherwise;
+
bool lockteams;
// ========================== Global teams API ================================
/// \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.
#include <common/weapons/_all.qh>
#include <common/stats.qh>
+ float autocvar_sv_accuracy_data_share = 1;
+
.bool cvar_cl_accuracy_data_share;
REPLICATE(cvar_cl_accuracy_data_share, bool, "cl_accuracy_data_share");
.bool cvar_cl_accuracy_data_receive;
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);
vector md = ent.(weaponentity).movedir;
vector vecs = ((md.x > 0) ? md : '0 0 0');
- // TODO this is broken - see 637056bea7bf7f5c9c0fc6113e94731a2767476 for an attempted fix
- // which fixes issue #1957 but causes #2129
vector dv = right * -vecs.y + up * vecs.z;
- w_shotorg = ent.origin + ent.view_ofs + dv;
+ w_shotorg = ent.origin + ent.view_ofs;
+ if(antilag)
+ {
+ if(CS(ent).antilag_debug)
+ tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + dv, MOVE_NORMAL, ent, CS(ent).antilag_debug);
+ else
+ tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + dv, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
+ }
+ else
+ tracebox(w_shotorg, mi, ma, w_shotorg + dv, MOVE_NORMAL, ent);
+ w_shotorg = trace_endpos;
// now move the shotorg forward as much as requested if possible
if(antilag)
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);
#include <server/hook.qh>
#include <server/intermission.qh>
#include <server/ipban.qh>
+ #include <server/items/items.qh>
#include <server/main.qh>
#include <server/mapvoting.qh>
#include <server/mutators/_mod.qh>
// long
BADCVAR("hostname");
+ BADCVAR("hostname_full");
BADCVAR("g_maplist");
BADCVAR("g_maplist_mostrecent");
BADCVAR("sv_motd");
+
+ BADPREFIX("g_teamnames_");
v = cvar_string(k);
d = cvar_defstring(k);
BADCVAR("g_forced_respawn");
BADCVAR("g_freezetag_point_leadlimit");
BADCVAR("g_freezetag_point_limit");
+ BADCVAR("g_freezetag_revive_respawn");
+ BADCVAR("g_freezetag_round_stop");
+ BADCVAR("g_freezetag_round_respawn");
BADCVAR("g_glowtrails");
BADCVAR("g_hats");
BADCVAR("g_casings");
BADPREFIX("sv_timeout_");
BADPREFIX("sv_vote_");
BADPREFIX("timelimit_");
+ BADPREFIX("sv_chat_");
+ BADPREFIX("sv_jingle_");
// allowed changes to server admins (please sync this to server.cfg)
// vi commands:
world_initialized = 1;
__spawnfunc_spawn_all();
+
+ if(!warmup_stage)
+ round_handler_Activate(true);
}
spawnfunc(light)
*/
//pos = FindIntermission ();
+
+ sound(NULL, CH_INFO, SND_ENDMATCH, VOL_BASE, ATTN_NONE);
VoteReset();
WeaponStats_Shutdown();
Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_Null); // kill all centerprints now
+
+ // send winner notification
+ if(teamplay) {
+ Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, APP_TEAM_NUM(WinningConditionHelper_winnerteam, ANNCE_WINS));
+ }
if(autocvar_sv_eventlog)
GameLogEcho(":gameover");
});
target_music_kill();
+
+ // z411
+ if(autocvar_sv_jingle_end) {
+ int jingles_len = 0;
+ string jingles[32];
+ jingles[0] = "";
+
+ FOREACH_WORD(autocvar_sv_jingle_end_list, it,
+ {
+ jingles[jingles_len] = it;
+ jingles_len++;
+ });
+
+ if(jingles_len) {
+ int song_to_play = rint(random() * (jingles_len - 1));
+
+ FOREACH_CLIENT(IS_REAL_CLIENT(it),
+ {
+ stuffcmd(it, "cd stop\n");
+ _sound(it, CH_INFO, strcat("jingle/", jingles[song_to_play], ".ogg"), VOL_BASE * autocvar_sv_jingle_end_volume, ATTEN_NORM);
+ });
+ }
+ }
if(autocvar_g_campaign)
CampaignPreIntermission();
//add one more overtime by simply extending the timelimit
cvar_set("timelimit", ftos(autocvar_timelimit + autocvar_timelimit_overtime));
Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_OVERTIME_TIME, autocvar_timelimit_overtime * 60);
+
+ sound(NULL, CH_INFO, SND_OVERTIME, VOL_BASE, ATTN_NONE);
+ if(checkrules_overtimesadded == 1) {
+ Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_OVERTIME);
+ overtime_starttime = time;
+ }
}
float GetWinningCode(float fraglimitreached, float equality)
FOREACH_CLIENT(IS_PLAYER(it), { it.winning = 0; });
}
-int fragsleft_last;
float WinningCondition_Scores(float limit, float leadlimit)
{
// TODO make everything use THIS winning condition (except LMS)
if(MUTATOR_CALLHOOK(Scores_CountFragsRemaining))
{
- float fragsleft;
if (checkrules_suddendeathend && time >= checkrules_suddendeathend)
{
fragsleft = 1;
fragsleft_last = fragsleft;
}
}
-
+
+ // z411
+ if (WinningConditionHelper_winner != WinningConditionHelper_winner_last && (WinningConditionHelper_second || WinningConditionHelper_equality))
+ {
+ if (WinningConditionHelper_equality)
+ {
+ Send_Notification(NOTIF_ONE, WinningConditionHelper_equality_one, MSG_ANNCE, ANNCE_LEAD_TIED);
+ Send_Notification(NOTIF_ONE, WinningConditionHelper_equality_two, MSG_ANNCE, ANNCE_LEAD_TIED);
+ }
+ else
+ {
+ Send_Notification(NOTIF_ONE, WinningConditionHelper_winner, MSG_ANNCE, ANNCE_LEAD_GAINED);
+ Send_Notification(NOTIF_ONE, WinningConditionHelper_second, MSG_ANNCE, ANNCE_LEAD_LOST);
+ }
+
+ WinningConditionHelper_winner_last = WinningConditionHelper_winner;
+ }
+
bool fraglimit_reached = (limit && WinningConditionHelper_topscore >= limit);
bool leadlimit_reached = (leadlimit && WinningConditionHelper_topscore - WinningConditionHelper_secondscore >= leadlimit);
// again, but this shouldn't hurt
return;
}
+
+ // z411 don't check rules if we're in a timeout
+ if (game_timeout) return;
float timelimit = autocvar_timelimit * 60;
float fraglimit = autocvar_fraglimit;
Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_RACE_FINISHLAP);
else
Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_OVERTIME_FRAG);
+ sound(NULL, CH_INFO, SND_OVERTIME, VOL_BASE, ATTN_NONE);
+ Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_SUDDENDEATH);
}
}
else
#include <common/weapons/_all.qh>
+ bool autocvar__sv_init;
+ bool autocvar_g_use_ammunition;
+ bool autocvar_g_jetpack;
+ bool autocvar_g_warmup_allguns;
+ bool autocvar_g_warmup_allow_timeout;
+ #define autocvar_g_weaponarena cvar_string("g_weaponarena")
+ string autocvar_quit_and_redirect;
+ float autocvar_quit_and_redirect_timer;
+ bool autocvar_quit_when_empty;
+ string autocvar_sessionid;
+ bool autocvar_sv_curl_serverpackages_auto;
+ bool autocvar_sv_db_saveasdump;
+ bool autocvar_sv_logscores_bots;
+ bool autocvar_sv_logscores_console;
+ bool autocvar_sv_logscores_file;
+ string autocvar_sv_logscores_filename;
+ float autocvar_sv_mapchange_delay;
+ float autocvar_timelimit_increment;
+ float autocvar_timelimit_decrement;
+ float autocvar_timelimit_min;
+ float autocvar_timelimit_max;
+ float autocvar_timelimit_overtime;
+ int autocvar_timelimit_overtimes;
+ float autocvar_timelimit_suddendeath;
+
++// z411
++bool autocvar_sv_jingle_end;
++string autocvar_sv_jingle_end_list;
++float autocvar_sv_jingle_end_volume;
++
float checkrules_equality;
float checkrules_suddendeathwarning;
float checkrules_suddendeathend;
-float checkrules_overtimesadded; //how many overtimes have been already added
+//float checkrules_overtimesadded; //how many overtimes have been already added
// flag set on worldspawn so that the code knows if it is dedicated or not
bool server_is_dedicated;
string gamemode_name;
+int fragsleft;
+int fragsleft_last;
+
string clientstuff;
string matchid;