#include "../common/deathtypes.qh"
#include "../common/mapinfo.qh"
#include "../common/nades.qh"
+
+#include "../server/mutators/gamemode_ctf.qh"
+
#include "../common/stats.qh"
#include "../csqcmodellib/cl_player.qh"
return bound(1, floor((sqrt(4 * item_aspect * aspect * item_count + aspect * aspect) + aspect + 0.5) / 2), item_count);
}
-vector HUD_GetTableSize(int item_count, vector psize, float item_aspect)
+vector HUD_GetTableSize_BestItemAR(int item_count, vector psize, float item_aspect)
{
float columns, rows;
float ratio, best_ratio = 0;
vector color;
// check to see if we want to continue
- if(hud != HUD_NORMAL) { return; }
+ if(intermission == 2) return;
+ if(hud != HUD_NORMAL) return;
if(!autocvar__hud_configure)
{
vector padded_panel_size = panel_size - '2 2 0' * panel_bg_padding;
// get the all-weapons layout
- vector table_size = HUD_GetTableSize(WEP_COUNT, padded_panel_size, aspect);
+ vector table_size = HUD_GetTableSize_BestItemAR(WEP_COUNT, padded_panel_size, aspect);
columns = table_size.x;
rows = table_size.y;
weapon_size.x = padded_panel_size.x / columns;
if(!rows) // if rows is > 0 onlyowned code has already updated these vars
{
- vector table_size = HUD_GetTableSize(WEP_COUNT, panel_size, aspect);
+ vector table_size = HUD_GetTableSize_BestItemAR(WEP_COUNT, panel_size, aspect);
columns = table_size.x;
rows = table_size.y;
weapon_size.x = panel_size.x / columns;
// draw items
row = column = 0;
vector label_size = '1 1 0' * min(weapon_size.x, weapon_size.y) * bound(0, autocvar_hud_panel_weapons_label_scale, 1);
+ vector noncurrent_pos = '0 0 0';
+ vector noncurrent_size = weapon_size * bound(0, autocvar_hud_panel_weapons_noncurrent_scale, 1);
+ float noncurrent_alpha = panel_fg_alpha * bound(0, autocvar_hud_panel_weapons_noncurrent_alpha, 1);
+ bool isCurrent;
+
for(i = 0; i <= WEP_LAST-WEP_FIRST; ++i)
{
// retrieve information about the current weapon to be drawn
self = weaponorder[i];
weapon_id = self.impulse;
+ isCurrent = (self.weapon == switchweapon);
// skip if this weapon doesn't exist
if(!self || weapon_id < 0) { continue; }
continue;
// figure out the drawing position of weapon
- weapon_pos = (panel_pos
- + eX * column * weapon_size.x
- + eY * row * weapon_size.y);
+ weapon_pos = (panel_pos + eX * column * weapon_size.x + eY * row * weapon_size.y);
+ noncurrent_pos.x = weapon_pos.x + (weapon_size.x - noncurrent_size.x) / 2;
+ noncurrent_pos.y = weapon_pos.y + (weapon_size.y - noncurrent_size.y) / 2;
// draw background behind currently selected weapon
- if(self.weapon == switchweapon)
+ if(isCurrent)
drawpic_aspect_skin(weapon_pos, "weapon_current_bg", weapon_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
// draw the weapon accuracy
if(weapons_stat & WepSet_FromWeapon(self.weapon))
{
// draw the weapon image
- drawpic_aspect_skin(weapon_pos, self.model2, weapon_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ if(isCurrent)
+ drawpic_aspect_skin(weapon_pos, self.model2, weapon_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ else
+ drawpic_aspect_skin(noncurrent_pos, self.model2, noncurrent_size, '1 1 1', noncurrent_alpha, DRAWFLAG_NORMAL);
// draw weapon label string
switch(autocvar_hud_panel_weapons_label)
}
else // draw a "ghost weapon icon" if you don't have the weapon
{
- drawpic_aspect_skin(weapon_pos, self.model2, weapon_size, '0 0 0', panel_fg_alpha * 0.5, DRAWFLAG_NORMAL);
+ drawpic_aspect_skin(noncurrent_pos, self.model2, noncurrent_size, '0.2 0.2 0.2', panel_fg_alpha * 0.5, DRAWFLAG_NORMAL);
}
// draw the complain message
float nade_statuschange_time;
void HUD_Ammo(void)
{
+ if(intermission == 2) return;
if(hud != HUD_NORMAL) return;
if(!autocvar__hud_configure)
{
void HUD_Powerups(void)
{
float strength_time, shield_time, superweapons_time;
+ if(intermission == 2) return;
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_powerups) return;
void HUD_HealthArmor(void)
{
int armor, health, fuel;
+ if(intermission == 2) return;
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_healtharmor) return;
void HUD_Notify(void)
{
+ if(intermission == 2) return;
if (!autocvar__hud_configure)
if (!autocvar_hud_panel_notify)
return;
void HUD_Timer(void)
{
+ if(intermission == 2) return;
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_timer) return;
//
void HUD_Radar(void)
{
+ if(intermission == 2) return;
if (!autocvar__hud_configure)
{
if (hud_panel_radar_maximized)
void HUD_Score(void)
{
+ if(intermission == 2) return;
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_score) return;
//
void HUD_RaceTimer (void)
{
+ if(intermission == 2) return;
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_racetimer) return;
void HUD_Vote(void)
{
+ if(intermission == 2) return;
if(autocvar_cl_allow_uid2name == -1 && (gametype == MAPINFO_TYPE_CTS || gametype == MAPINFO_TYPE_RACE || (serverflags & SERVERFLAG_PLAYERSTATS)))
{
vote_active = 1;
}
// CTF HUD modicon section
-float redflag_prevframe, blueflag_prevframe; // status during previous frame
-int redflag_prevstatus, blueflag_prevstatus; // last remembered status
-float redflag_statuschange_time, blueflag_statuschange_time; // time when the status changed
+int redflag_prevframe, blueflag_prevframe, yellowflag_prevframe, pinkflag_prevframe, neutralflag_prevframe; // status during previous frame
+int redflag_prevstatus, blueflag_prevstatus, yellowflag_prevstatus, pinkflag_prevstatus, neutralflag_prevstatus; // last remembered status
+float redflag_statuschange_time, blueflag_statuschange_time, yellowflag_statuschange_time, pinkflag_statuschange_time, neutralflag_statuschange_time; // time when the status changed
void HUD_Mod_CTF_Reset(void)
{
- redflag_prevstatus = blueflag_prevstatus = redflag_prevframe = blueflag_prevframe = redflag_statuschange_time = blueflag_statuschange_time = 0;
+ redflag_prevstatus = blueflag_prevstatus = yellowflag_prevstatus = pinkflag_prevstatus = neutralflag_prevstatus = 0;
+ redflag_prevframe = blueflag_prevframe = yellowflag_prevframe = pinkflag_prevframe = neutralflag_prevframe = 0;
+ redflag_statuschange_time = blueflag_statuschange_time = yellowflag_statuschange_time = pinkflag_statuschange_time = neutralflag_statuschange_time = 0;
}
void HUD_Mod_CTF(vector pos, vector mySize)
{
- vector redflag_pos, blueflag_pos;
+ vector redflag_pos, blueflag_pos, yellowflag_pos, pinkflag_pos, neutralflag_pos;
vector flag_size;
float f; // every function should have that
- int redflag, blueflag; // current status
- float redflag_statuschange_elapsedtime, blueflag_statuschange_elapsedtime; // time since the status changed
- int stat_items;
+ int redflag, blueflag, yellowflag, pinkflag, neutralflag; // current status
+ float redflag_statuschange_elapsedtime, blueflag_statuschange_elapsedtime, yellowflag_statuschange_elapsedtime, pinkflag_statuschange_elapsedtime, neutralflag_statuschange_elapsedtime; // time since the status changed
+ bool ctf_oneflag; // one-flag CTF mode enabled/disabled
+ int stat_items = getstati(STAT_CTF_FLAGSTATUS, 0, 24);
+ float fs, fs2, fs3, size1, size2;
+ vector e1, e2;
- stat_items = getstati(STAT_ITEMS, 0, 24);
- redflag = (stat_items/IT_RED_FLAG_TAKEN) & 3;
- blueflag = (stat_items/IT_BLUE_FLAG_TAKEN) & 3;
+ redflag = (stat_items/CTF_RED_FLAG_TAKEN) & 3;
+ blueflag = (stat_items/CTF_BLUE_FLAG_TAKEN) & 3;
+ yellowflag = (stat_items/CTF_YELLOW_FLAG_TAKEN) & 3;
+ pinkflag = (stat_items/CTF_PINK_FLAG_TAKEN) & 3;
+ neutralflag = (stat_items/CTF_NEUTRAL_FLAG_TAKEN) & 3;
+
+ ctf_oneflag = (stat_items & CTF_FLAG_NEUTRAL);
- if(redflag || blueflag)
- mod_active = 1;
- else
- mod_active = 0;
+ mod_active = (redflag || blueflag || yellowflag || pinkflag || neutralflag);
- if(autocvar__hud_configure)
- {
+ if (autocvar__hud_configure) {
redflag = 1;
blueflag = 2;
+ if (team_count >= 3)
+ yellowflag = 2;
+ if (team_count >= 4)
+ pinkflag = 3;
+ ctf_oneflag = neutralflag = 0; // disable neutral flag in hud editor?
}
// when status CHANGES, set old status into prevstatus and current status into status
- if (redflag != redflag_prevframe)
- {
- redflag_statuschange_time = time;
- redflag_prevstatus = redflag_prevframe;
- redflag_prevframe = redflag;
- }
-
- if (blueflag != blueflag_prevframe)
- {
- blueflag_statuschange_time = time;
- blueflag_prevstatus = blueflag_prevframe;
- blueflag_prevframe = blueflag;
- }
-
- redflag_statuschange_elapsedtime = time - redflag_statuschange_time;
- blueflag_statuschange_elapsedtime = time - blueflag_statuschange_time;
-
- float BLINK_FACTOR = 0.15;
- float BLINK_BASE = 0.85;
+ #define X(team) do { \
+ if (team##flag != team##flag_prevframe) { \
+ team##flag_statuschange_time = time; \
+ team##flag_prevstatus = team##flag_prevframe; \
+ team##flag_prevframe = team##flag; \
+ } \
+ team##flag_statuschange_elapsedtime = time - team##flag_statuschange_time; \
+ } while (0)
+ X(red);
+ X(blue);
+ X(yellow);
+ X(pink);
+ X(neutral);
+ #undef X
+
+ const float BLINK_FACTOR = 0.15;
+ const float BLINK_BASE = 0.85;
// note:
// RMS = sqrt(BLINK_BASE^2 + 0.5 * BLINK_FACTOR^2)
// thus
// BLINK_BASE = sqrt(RMS^2 - 0.5 * BLINK_FACTOR^2)
// ensure RMS == 1
- float BLINK_FREQ = 5; // circle frequency, = 2*pi*frequency in hertz
-
- string red_icon, red_icon_prevstatus;
- float red_alpha, red_alpha_prevstatus;
- red_alpha = red_alpha_prevstatus = 1;
- switch(redflag) {
- case 1: red_icon = "flag_red_taken"; break;
- case 2: red_icon = "flag_red_lost"; break;
- case 3: red_icon = "flag_red_carrying"; red_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
+ const float BLINK_FREQ = 5; // circle frequency, = 2*pi*frequency in hertz
+
+ #define X(team, cond) \
+ string team##_icon, team##_icon_prevstatus; \
+ int team##_alpha, team##_alpha_prevstatus; \
+ team##_alpha = team##_alpha_prevstatus = 1; \
+ do { \
+ switch (team##flag) { \
+ case 1: team##_icon = "flag_" #team "_taken"; break; \
+ case 2: team##_icon = "flag_" #team "_lost"; break; \
+ case 3: team##_icon = "flag_" #team "_carrying"; team##_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; \
+ default: \
+ if ((stat_items & CTF_SHIELDED) && (cond)) { \
+ team##_icon = "flag_" #team "_shielded"; \
+ } else { \
+ team##_icon = string_null; \
+ } \
+ break; \
+ } \
+ switch (team##flag_prevstatus) { \
+ case 1: team##_icon_prevstatus = "flag_" #team "_taken"; break; \
+ case 2: team##_icon_prevstatus = "flag_" #team "_lost"; break; \
+ case 3: team##_icon_prevstatus = "flag_" #team "_carrying"; team##_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; \
+ default: \
+ if (team##flag == 3) { \
+ team##_icon_prevstatus = "flag_" #team "_carrying"; /* make it more visible */\
+ } else if((stat_items & CTF_SHIELDED) && (cond)) { \
+ team##_icon_prevstatus = "flag_" #team "_shielded"; \
+ } else { \
+ team##_icon_prevstatus = string_null; \
+ } \
+ break; \
+ } \
+ } while (0)
+ X(red, myteam != NUM_TEAM_1);
+ X(blue, myteam != NUM_TEAM_2);
+ X(yellow, myteam != NUM_TEAM_3);
+ X(pink, myteam != NUM_TEAM_4);
+ X(neutral, true);
+ #undef X
+
+ if (ctf_oneflag) {
+ // hacky, but these aren't needed
+ red_icon = red_icon_prevstatus = blue_icon = blue_icon_prevstatus = yellow_icon = yellow_icon_prevstatus = pink_icon = pink_icon_prevstatus = string_null;
+ fs = fs2 = fs3 = 1;
+ } else switch (team_count) {
default:
- if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_2))
- red_icon = "flag_red_shielded";
- else
- red_icon = string_null;
- break;
- }
- switch(redflag_prevstatus) {
- case 1: red_icon_prevstatus = "flag_red_taken"; break;
- case 2: red_icon_prevstatus = "flag_red_lost"; break;
- case 3: red_icon_prevstatus = "flag_red_carrying"; red_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
- default:
- if(redflag == 3)
- red_icon_prevstatus = "flag_red_carrying"; // make it more visible
- else if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_2))
- red_icon_prevstatus = "flag_red_shielded";
- else
- red_icon_prevstatus = string_null;
- break;
+ case 2: fs = 0.5; fs2 = 0.5; fs3 = 0.5; break;
+ case 3: fs = 1; fs2 = 0.35; fs3 = 0.35; break;
+ case 4: fs = 0.75; fs2 = 0.25; fs3 = 0.5; break;
}
- string blue_icon, blue_icon_prevstatus;
- float blue_alpha, blue_alpha_prevstatus;
- blue_alpha = blue_alpha_prevstatus = 1;
- switch(blueflag) {
- case 1: blue_icon = "flag_blue_taken"; break;
- case 2: blue_icon = "flag_blue_lost"; break;
- case 3: blue_icon = "flag_blue_carrying"; blue_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
- default:
- if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_1))
- blue_icon = "flag_blue_shielded";
- else
- blue_icon = string_null;
- break;
- }
- switch(blueflag_prevstatus) {
- case 1: blue_icon_prevstatus = "flag_blue_taken"; break;
- case 2: blue_icon_prevstatus = "flag_blue_lost"; break;
- case 3: blue_icon_prevstatus = "flag_blue_carrying"; blue_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
- default:
- if(blueflag == 3)
- blue_icon_prevstatus = "flag_blue_carrying"; // make it more visible
- else if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_1))
- blue_icon_prevstatus = "flag_blue_shielded";
- else
- blue_icon_prevstatus = string_null;
- break;
+ if (mySize_x > mySize_y) {
+ size1 = mySize_x;
+ size2 = mySize_y;
+ e1 = eX;
+ e2 = eY;
+ } else {
+ size1 = mySize_y;
+ size2 = mySize_x;
+ e1 = eY;
+ e2 = eX;
}
- if(mySize.x > mySize.y) {
- if (myteam == NUM_TEAM_1) { // always draw own flag on left
+ switch (myteam) {
+ default:
+ case NUM_TEAM_1: {
redflag_pos = pos;
- blueflag_pos = pos + eX * 0.5 * mySize.x;
- } else {
- blueflag_pos = pos;
- redflag_pos = pos + eX * 0.5 * mySize.x;
+ blueflag_pos = pos + eX * fs2 * size1;
+ yellowflag_pos = pos - eX * fs2 * size1;
+ pinkflag_pos = pos + eX * fs3 * size1;
+ break;
}
- flag_size = eX * 0.5 * mySize.x + eY * mySize.y;
- } else {
- if (myteam == NUM_TEAM_1) { // always draw own flag on left
- redflag_pos = pos;
- blueflag_pos = pos + eY * 0.5 * mySize.y;
- } else {
+ case NUM_TEAM_2: {
+ redflag_pos = pos + eX * fs2 * size1;
blueflag_pos = pos;
- redflag_pos = pos + eY * 0.5 * mySize.y;
+ yellowflag_pos = pos - eX * fs2 * size1;
+ pinkflag_pos = pos + eX * fs3 * size1;
+ break;
+ }
+ case NUM_TEAM_3: {
+ redflag_pos = pos + eX * fs3 * size1;
+ blueflag_pos = pos - eX * fs2 * size1;
+ yellowflag_pos = pos;
+ pinkflag_pos = pos + eX * fs2 * size1;
+ break;
+ }
+ case NUM_TEAM_4: {
+ redflag_pos = pos - eX * fs2 * size1;
+ blueflag_pos = pos + eX * fs3 * size1;
+ yellowflag_pos = pos + eX * fs2 * size1;
+ pinkflag_pos = pos;
+ break;
}
- flag_size = eY * 0.5 * mySize.y + eX * mySize.x;
}
-
- f = bound(0, redflag_statuschange_elapsedtime*2, 1);
- if(red_icon_prevstatus && f < 1)
- drawpic_aspect_skin_expanding(redflag_pos, red_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * red_alpha_prevstatus, DRAWFLAG_NORMAL, f);
- if(red_icon)
- drawpic_aspect_skin(redflag_pos, red_icon, flag_size, '1 1 1', panel_fg_alpha * red_alpha * f, DRAWFLAG_NORMAL);
-
- f = bound(0, blueflag_statuschange_elapsedtime*2, 1);
- if(blue_icon_prevstatus && f < 1)
- drawpic_aspect_skin_expanding(blueflag_pos, blue_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * blue_alpha_prevstatus, DRAWFLAG_NORMAL, f);
- if(blue_icon)
- drawpic_aspect_skin(blueflag_pos, blue_icon, flag_size, '1 1 1', panel_fg_alpha * blue_alpha * f, DRAWFLAG_NORMAL);
+ neutralflag_pos = pos;
+ flag_size = e1 * fs * size1 + e2 * size2;
+
+ #define X(team) do { \
+ f = bound(0, team##flag_statuschange_elapsedtime * 2, 1); \
+ if (team##_icon_prevstatus && f < 1) \
+ drawpic_aspect_skin_expanding(team##flag_pos, team##_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * team##_alpha_prevstatus, DRAWFLAG_NORMAL, f); \
+ if (team##_icon) \
+ drawpic_aspect_skin(team##flag_pos, team##_icon, flag_size, '1 1 1', panel_fg_alpha * team##_alpha * f, DRAWFLAG_NORMAL); \
+ } while (0)
+ X(red);
+ X(blue);
+ X(yellow);
+ X(pink);
+ X(neutral);
+ #undef X
}
// Keyhunt HUD modicon section
void HUD_ModIcons(void)
{
+ if(intermission == 2) return;
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_modicons) return;
//
void HUD_PressedKeys(void)
{
+ if(intermission == 2) return;
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_pressedkeys) return;
HUD_Panel_UpdateCvars();
+ if(intermission == 2)
+ {
+ // reserve some more space to the mapvote panel
+ // by resizing and moving chat panel to the bottom
+ panel_size.y = min(panel_size.y, vid_conheight * 0.2);
+ panel_pos.y = vid_conheight - panel_size.y - panel_bg_border * 2;
+ chat_posy = panel_pos.y;
+ chat_sizey = panel_size.y;
+ }
if(autocvar__con_chat_maximized && !autocvar__hud_configure) // draw at full screen height if maximized
{
panel_pos.y = panel_bg_border;
float frametimeavg2; // 2 frames ago
void HUD_EngineInfo(void)
{
+ //if(intermission == 2) return;
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_engineinfo) return;
} while(0)
void HUD_InfoMessages(void)
{
+ if(intermission == 2) return;
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_infomessages) return;
float physics_update_time, discrete_speed, discrete_acceleration;
void HUD_Physics(void)
{
+ if(intermission == 2) return;
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_physics) return;
float hud_configure_cp_generation_time;
void HUD_CenterPrint (void)
{
+ if(intermission == 2) return;
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_centerprint) return;
//
void HUD_Buffs(void)
{
+ if(intermission == 2) return;
int buffs = getstati(STAT_BUFFS, 0, 24);
if(!autocvar__hud_configure)
{
HUD_Configure_Frame();
- if(intermission == 2) // no hud during mapvote
- hud_fade_alpha = 0;
-
// panels that we want to be active together with the scoreboard
// they must fade only when the menu does
if(scoreboard_fade_alpha == 1)
}
hud_draw_maximized = 0;
- // draw panels in order specified by panel_order array
+ // draw panels in the order specified by panel_order array
for(i = HUD_PANEL_NUM - 1; i >= 0; --i)
(panel = hud_panel[panel_order[i]]).panel_draw();