]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/hud.qc
Merge remote branch 'origin/master' into terencehill/infinite_ammo
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud.qc
index 26d306f9a13050c0a1a73670231b9eba9a8ba84b..f8d8a3296e9713dcc99d34b83fc52928558aa557 100644 (file)
@@ -787,7 +787,7 @@ string GetAmmoPicture(float i)
        }
 }
 
-void DrawAmmoItem(vector myPos, vector mySize, float itemcode, float currently_selected)
+void DrawAmmoItem(vector myPos, vector mySize, float itemcode, float currently_selected, float infinite_ammo)
 {
        float a;
        if(autocvar__hud_configure)
@@ -799,7 +799,9 @@ void DrawAmmoItem(vector myPos, vector mySize, float itemcode, float currently_s
                a = getstati(GetAmmoStat(itemcode)); // how much ammo do we have of type itemcode?
 
        vector color;
-       if(a < 10)
+       if(infinite_ammo)
+               color = '0 0.5 0.75';
+       else if(a < 10)
                color = '0.7 0 0';
        else
                color = '1 1 1';
@@ -830,12 +832,12 @@ void DrawAmmoItem(vector myPos, vector mySize, float itemcode, float currently_s
 
     if(autocvar_hud_panel_ammo_text)
     {
-        if(a > 0)
+        if(a > 0 || infinite_ammo)
             drawstring_aspect(numpos, ftos(a), eX * (2/3) * mySize_x + eY * mySize_y, color, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
         else // "ghost" ammo count
             drawstring_aspect(numpos, ftos(a), eX * (2/3) * mySize_x + eY * mySize_y, '0 0 0', panel_fg_alpha * alpha * 0.5, DRAWFLAG_NORMAL);
     }
-       if(a > 0)
+       if(a > 0 || infinite_ammo)
                drawpic_aspect_skin(picpos, GetAmmoPicture(itemcode), '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
        else // "ghost" ammo icon
                drawpic_aspect_skin(picpos, GetAmmoPicture(itemcode), '1 1 0' * mySize_y, '0 0 0', panel_fg_alpha * alpha * 0.5, DRAWFLAG_NORMAL);
@@ -897,20 +899,23 @@ void HUD_Ammo(void)
                ammo_size_y = newSize;
        }
 
-       float i, stat_items, currently_selected;
+       float i, stat_items, currently_selected, infinite_ammo;
+       infinite_ammo = FALSE;
        if (autocvar_hud_panel_ammo_onlycurrent)
        {
                if(autocvar__hud_configure)
                {
-                       DrawAmmoItem(pos, ammo_size, 2, true); //show rockets
+                       DrawAmmoItem(pos, ammo_size, 2, true, FALSE); //show rockets
                        return;
                }
                stat_items = getstati(STAT_ITEMS);
+               if (stat_items & IT_UNLIMITED_WEAPON_AMMO)
+                       infinite_ammo = TRUE;
                for (i = 0; i < AMMO_COUNT; ++i) {
                        currently_selected = stat_items & GetAmmoItemCode(i);
                        if (currently_selected)
                        {
-                               DrawAmmoItem(pos, ammo_size, i, true);
+                               DrawAmmoItem(pos, ammo_size, i, true, infinite_ammo);
                                return;
                        }
                }
@@ -918,9 +923,11 @@ void HUD_Ammo(void)
        }
 
        stat_items = getstati(STAT_ITEMS);
+       if (stat_items & IT_UNLIMITED_WEAPON_AMMO)
+               infinite_ammo = TRUE;
        for (i = 0; i < AMMO_COUNT; ++i) {
                currently_selected = stat_items & GetAmmoItemCode(i);
-               DrawAmmoItem(pos + eX * column * (ammo_size_x + offset_x) + eY * row * (ammo_size_y + offset_y), ammo_size, i, currently_selected);
+               DrawAmmoItem(pos + eX * column * (ammo_size_x + offset_x) + eY * row * (ammo_size_y + offset_y), ammo_size, i, currently_selected, infinite_ammo);
                ++row;
                if(row >= rows)
                {
@@ -1839,55 +1846,55 @@ void HUD_Centerprint(string s1, string s2, float type, float msg)
        gentle = (autocvar_cl_gentle || autocvar_cl_gentle_messages);
        if(msg == MSG_SUICIDE) {
                if (type == DEATH_TEAMCHANGE) {
-                       centerprint(strcat(sprintf(_("You are now on: %s"), s1)));
+                       centerprint(sprintf(_("You are now on: %s"), s1));
                } else if (type == DEATH_AUTOTEAMCHANGE) {
-                       centerprint(strcat(sprintf(_("You have been moved into a different team to improve team balance\nYou are now on: %s"), s1)));
+                       centerprint(sprintf(_("You have been moved into a different team to improve team balance\nYou are now on: %s"), s1));
                } else if (type == DEATH_CAMP) {
                        if(gentle)
-                               centerprint(strcat(_("^1Reconsider your tactics, camper!")));
+                               centerprint(_("^1Reconsider your tactics, camper!"));
                        else
-                               centerprint(strcat(_("^1Die camper!")));
+                               centerprint(_("^1Die camper!"));
                } else if (type == DEATH_NOAMMO) {
                        if(gentle)
-                               centerprint(strcat(_("^1You are reinserted into the game for running out of ammo...")));
+                               centerprint(_("^1You are reinserted into the game for running out of ammo..."));
                        else
-                               centerprint(strcat(_("^1You were killed for running out of ammo...")));
+                               centerprint(_("^1You were killed for running out of ammo..."));
                } else if (type == DEATH_ROT) {
                        if(gentle)
-                               centerprint(strcat(_("^1You need to preserve your health")));
+                               centerprint(_("^1You need to preserve your health"));
                        else
-                               centerprint(strcat(_("^1You grew too old without taking your medicine")));
+                               centerprint(_("^1You grew too old without taking your medicine"));
                } else if (type == KILL_TEAM_RED || type == KILL_TEAM_BLUE) {
                        if(gentle)
-                               centerprint(strcat(_("^1Don't go against team mates!")));
+                               centerprint(_("^1Don't go against team mates!"));
                        else
-                               centerprint(strcat(_("^1Don't shoot your team mates!")));
+                               centerprint(_("^1Don't shoot your team mates!"));
                } else if (type == DEATH_QUIET) {
                        // do nothing
                } else { // generic message
                        if(gentle)
-                               centerprint(strcat(_("^1You need to be more careful!")));
+                               centerprint(_("^1You need to be more careful!"));
                        else
-                               centerprint(strcat(_("^1You killed your own dumb self!")));
+                               centerprint(_("^1You killed your own dumb self!"));
                }
        } else if(msg == MSG_KILL) {
                if (type == KILL_TEAM_RED || type == KILL_TEAM_BLUE) {
                        if(gentle) {
-                               centerprint(strcat(sprintf(_("^1Moron! You went against ^7%s^1, a team mate!"), s1)));
+                               centerprint(sprintf(_("^1Moron! You went against ^7%s^1, a team mate!"), s1));
                        } else {
-                               centerprint(strcat(sprintf(_("^1Moron! You fragged ^7%s^1, a team mate!"), s1)));
+                               centerprint(sprintf(_("^1Moron! You fragged ^7%s^1, a team mate!"), s1));
                        }
                } else if (type == KILL_FIRST_BLOOD) {
                        if(gentle) {
-                               centerprint(strcat(_("^1First score")));
+                               centerprint(_("^1First score"));
                        } else {
-                               centerprint(strcat(_("^1First blood")));
+                               centerprint(_("^1First blood"));
                        }
                } else if (type == KILL_FIRST_VICTIM) {
                        if(gentle) {
-                               centerprint(strcat(_("^1First casualty")));
+                               centerprint(_("^1First casualty"));
                        } else {
-                               centerprint(strcat(_("^1First victim")));
+                               centerprint(_("^1First victim"));
                        }
                } else if (type == KILL_TYPEFRAG) { // s2 contains "advanced kill messages" such as ping, handicap...
                        if(gentle) {
@@ -1916,7 +1923,7 @@ void HUD_Centerprint(string s1, string s2, float type, float msg)
                }
        } else if(msg == MSG_KILL_ACTION) {
                // TODO: invent more centerprints here?
-               centerprint(strcat(_("^1Watch your step!")));
+               centerprint(_("^1Watch your step!"));
        }
 }
 
@@ -2948,7 +2955,7 @@ void HUD_VoteWindow(void)
        pos = panel_pos;
        mySize = panel_size;
 
-       a = vote_alpha * bound(autocvar_hud_panel_vote_alreadyvoted_alpha, 1 - vote_highlighted, 1);
+       a = vote_alpha * (vote_highlighted ? autocvar_hud_panel_vote_alreadyvoted_alpha : 1);
        HUD_Panel_DrawBg(a);
        a = panel_fg_alpha * a;
 
@@ -2999,7 +3006,7 @@ void HUD_VoteWindow(void)
                drawsetcliparea(pos_x, pos_y, mySize_x * 0.5, mySize_y);
                drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_voted", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL);
        }
-       else if(vote_highlighted == 2) {
+       else if(vote_highlighted == -1) {
                drawsetcliparea(pos_x + 0.5 * mySize_x, pos_y, mySize_x * 0.5, mySize_y);
                drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_voted", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL);
        }
@@ -3018,10 +3025,6 @@ void HUD_VoteWindow(void)
        }
 
        drawresetcliparea();
-
-       if(!vote_active) {
-               vote_highlighted = 0;
-       }
 }
 
 // Mod icons panel (#10)
@@ -4130,7 +4133,8 @@ void HUD_Physics(void)
        if(!autocvar__hud_configure)
        {
                if(!autocvar_hud_panel_physics) return;
-               if(spectatee_status == -1 && autocvar_hud_panel_physics < 2) return;
+               if(spectatee_status == -1 && (autocvar_hud_panel_physics == 1 || autocvar_hud_panel_physics == 3)) return;
+               if(autocvar_hud_panel_physics == 3 && !(gametype == GAME_RACE || gametype == GAME_CTS)) return;
        }
        else
                hud_configure_active_panel = HUD_PANEL_PHYSICS;
@@ -4347,14 +4351,19 @@ void HUD_Physics(void)
                drawstring_aspect(panel_pos + acceleration_offset, strcat(ftos_decimals(acceleration, 2), "g"), panel_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 }
 
+// CenterPrint (#16)
+//
 #define CENTERPRINT_MAX_MSGS 10
 #define CENTERPRINT_MAX_ENTRIES 50
+#define CENTERPRINT_SPACING 0.7
 float cpm_index;
 string centerprint_messages[CENTERPRINT_MAX_MSGS];
 float centerprint_msgID[CENTERPRINT_MAX_MSGS];
 float centerprint_time[CENTERPRINT_MAX_MSGS];
 float centerprint_expire_time[CENTERPRINT_MAX_MSGS];
 float centerprint_countdown_num[CENTERPRINT_MAX_MSGS];
+float centerprint_fadetime;
+float centerprint_showing;
 
 void centerprint_generic(float new_id, string strMessage, float duration, float countdown_num)
 {
@@ -4363,15 +4372,47 @@ void centerprint_generic(float new_id, string strMessage, float duration, float
        if(strMessage == "" && new_id == 0)
                return;
 
-       if(duration == 0)
-               duration = max(1, autocvar_hud_panel_centerprint_time);
+       // strip trailing newlines
+       j = strlen(strMessage) - 1;
+       while(substring(strMessage, j, 1) == "\n" && j >= 0)
+               --j;
+       if (j < strlen(strMessage) - 1)
+               strMessage = substring(strMessage, 0, j + 1);
+
+       if(strMessage == "" && new_id == 0)
+               return;
+
+       // strip leading newlines
+       j = 0;
+       while(substring(strMessage, j, 1) == "\n" && j < strlen(strMessage))
+               ++j;
+       if (j > 0)
+               strMessage = substring(strMessage, j, strlen(strMessage) - j);
+
+       if(strMessage == "" && new_id == 0)
+               return;
+
+       if (!centerprint_showing)
+               centerprint_showing = TRUE;
+
+       centerprint_fadetime = bound(0, autocvar_hud_panel_centerprint_fadetime, 1);
 
        for (i=0, j=cpm_index; i<CENTERPRINT_MAX_MSGS; ++i, ++j)
        {
                if (j == CENTERPRINT_MAX_MSGS)
                        j = 0;
                if (new_id && new_id == centerprint_msgID[j])
+               {
+                       if (strMessage == "" && centerprint_messages[j] != "" && centerprint_countdown_num[j] == 0)
+                       {
+                               // fade out the current msg (duration and countdown_num are ignored)
+                               centerprint_time[j] = centerprint_fadetime;
+                               if (centerprint_expire_time[j] > time + centerprint_fadetime || centerprint_expire_time[j] < time)
+                                       centerprint_expire_time[j] = time + centerprint_fadetime;
+                               return;
+                       }
                        break; // found a msg with the same id, at position j
+               }
        }
 
        if (i == CENTERPRINT_MAX_MSGS)
@@ -4390,6 +4431,8 @@ void centerprint_generic(float new_id, string strMessage, float duration, float
                centerprint_time[j] = -1;
        else
        {
+               if(duration == 0)
+                       duration = max(1, autocvar_hud_panel_centerprint_time);
                centerprint_time[j] = duration;
                centerprint_expire_time[j] = time + duration;
        }
@@ -4401,17 +4444,49 @@ void centerprint(string strMessage)
        centerprint_generic(0, strMessage, autocvar_hud_panel_centerprint_time, 0);
 }
 
-// CenterPrint (#16)
-//
+void reset_centerprint_messages(void)
+{
+       float i;
+       for (i=0; i<CENTERPRINT_MAX_MSGS; ++i)
+       {
+               centerprint_expire_time[i] = 0;
+               centerprint_time[i] = 1;
+               centerprint_msgID[i] = 0;
+               if(centerprint_messages[i])
+                       strunzone(centerprint_messages[i]);
+               centerprint_messages[i] = string_null;
+       }
+}
+float hud_configure_cp_generation_time;
 void HUD_CenterPrint (void)
 {
        if(!autocvar__hud_configure)
        {
                if(!autocvar_hud_panel_centerprint) return;
+
+               if (hud_configure_prev && hud_configure_prev != -1)
+                       reset_centerprint_messages();
        }
        else
+       {
                hud_configure_active_panel = HUD_PANEL_CENTERPRINT;
 
+               if (!hud_configure_prev)
+                       reset_centerprint_messages();
+               if (time > hud_configure_cp_generation_time)
+               {
+                       float r;
+                       r = random();
+                       if (r > 0.9)
+                               centerprint_generic(floor(r*1000), strcat(sprintf("^3Countdown message at time %s", seconds_tostring(time)), ", seconds left: %d"), 1, 10);
+                       else if (r > 0.8)
+                               centerprint_generic(0, sprintf("^1Multiline message at time %s that\n^1lasts longer than normal", seconds_tostring(time)), 20, 0);
+                       else
+                               centerprint(sprintf("Message at time %s", seconds_tostring(time)));
+                       hud_configure_cp_generation_time = time + 1 + random()*4;
+               }
+       }
+
        HUD_Panel_UpdateCvars(centerprint);
 
        // this panel doesn't fade when showing the scoreboard
@@ -4430,6 +4505,10 @@ void HUD_CenterPrint (void)
        }
 
        HUD_Panel_DrawBg(1);
+
+       if (!centerprint_showing)
+               return;
+
        if(panel_bg_padding)
        {
                panel_pos += '1 1 0' * panel_bg_padding;
@@ -4441,31 +4520,28 @@ void HUD_CenterPrint (void)
        // entries = bound(1, floor(CENTERPRINT_MAX_ENTRIES * 4 * panel_size_y/panel_size_x), CENTERPRINT_MAX_ENTRIES);
        // height = panel_size_y/entries;
        // fontsize = '1 1 0' * height;
-       height = vid_conheight/40 * autocvar_hud_panel_centerprint_fontscale;
+       height = vid_conheight/50 * autocvar_hud_panel_centerprint_fontscale;
        fontsize = '1 1 0' * height;
        entries = bound(1, floor(panel_size_y/height), CENTERPRINT_MAX_ENTRIES);
 
        float i, j, k, n;
-       float a, sz, fade, align, next_msg_pos_y;
+       float a, sz, align, current_msg_pos_y, msg_size;
        vector pos;
        string ts;
 
+       n = -1; // if no msg will be displayed, n stays -1
+
        pos = panel_pos;
        if (autocvar_hud_panel_centerprint_flip)
-               pos_y += panel_size_y - fontsize_y;
-       fade = min(autocvar_hud_panel_centerprint_time/8, 0.25);
+               pos_y += panel_size_y;
        align = bound(0, autocvar_hud_panel_centerprint_align, 1);
-       float alpha_factor;
-       alpha_factor = panel_fg_alpha;
-       if (autocvar__menu_alpha)
-               alpha_factor *= hud_fade_alpha;
        for (i=0, j=cpm_index; i<CENTERPRINT_MAX_MSGS; ++i, ++j)
        {
                if (j == CENTERPRINT_MAX_MSGS)
                        j = 0;
-               if (centerprint_time[j] > 0 && centerprint_expire_time[j] < time)
+               if (centerprint_expire_time[j] < time)
                {
-                       if (centerprint_countdown_num[j])
+                       if (centerprint_countdown_num[j] && centerprint_time[j] > 0)
                        {
                                centerprint_countdown_num[j] = centerprint_countdown_num[j] - 1;
                                if (centerprint_countdown_num[j] == 0)
@@ -4475,14 +4551,14 @@ void HUD_CenterPrint (void)
                        else
                                continue;
                }
-               if (centerprint_time[j] < 0 || centerprint_expire_time[j] - fade > time)
+               if (centerprint_time[j] < 0 || centerprint_expire_time[j] - centerprint_fadetime > time)
                {
-                       a = 1 * alpha_factor;
-                       sz = 1;
+                       a = bound(0, (time - (centerprint_expire_time[j] - centerprint_time[j])) / centerprint_fadetime, 1);
+                       sz = 0.8 + a * (1 - 0.8);
                }
                else if (centerprint_expire_time[j] > time)
                {
-                       a = (centerprint_expire_time[j] - time) / fade * alpha_factor;
+                       a = (centerprint_expire_time[j] - time) / centerprint_fadetime;
                        sz = 0.8 + a * (1 - 0.8);
                }
 
@@ -4497,51 +4573,65 @@ void HUD_CenterPrint (void)
                        for(k = 0; k < n; ++k)
                        {
                                getWrappedLine_remaining = argv(k);
-                               ts = getWrappedLine(panel_size_x, fontsize, stringwidth_colors);
-                               if (ts != "")
-                                       pos_y -= fontsize_y * 1.5;
-                               else
-                                       pos_y -= fontsize_y;
-                               if (pos_y < panel_pos_y) // check if the next line can be shown
-                                       return;
+                               while(getWrappedLine_remaining)
+                               {
+                                       ts = getWrappedLine(panel_size_x * sz, fontsize, stringwidth_colors);
+                                       if (ts != "")
+                                               pos_y -= fontsize_y;
+                                       else
+                                               pos_y -= fontsize_y * CENTERPRINT_SPACING/2;
+                                       if (pos_y < panel_pos_y) // check if the next line can be shown
+                                       {
+                                               drawfontscale = '1 1 0';
+                                               return;
+                                       }
+                               }
                        }
-                       next_msg_pos_y = pos_y; // save pos of the next message
+                       current_msg_pos_y = pos_y; // save starting pos (first line) of the current message
                }
 
+               msg_size = pos_y;
                for(k = 0; k < n; ++k)
                {
                        getWrappedLine_remaining = argv(k);
                        while(getWrappedLine_remaining)
                        {
-                               ts = getWrappedLine(panel_size_x, fontsize, stringwidth_colors);
+                               ts = getWrappedLine(panel_size_x * sz, fontsize, stringwidth_colors);
                                if (ts != "")
                                {
                                        if (align)
                                                pos_x = panel_pos_x + (panel_size_x - stringwidth(ts, TRUE, fontsize)) * align;
-                                       drawcolorcodedstring(pos + '0 1 0' * 1.5 * (1 - sz) * fontsize_y, ts, fontsize, a, DRAWFLAG_NORMAL);
-                                       pos_y += fontsize_y * 1.5;
+                                       drawcolorcodedstring(pos + eY * 0.5 * (1 - sz) * fontsize_y, ts, fontsize, a * panel_fg_alpha, DRAWFLAG_NORMAL);
+                                       pos_y += fontsize_y;
                                }
                                else
-                                       pos_y += fontsize_y;
-                               if (pos_y > panel_pos_y + panel_size_y - fontsize_y) // check if the next line can be shown
+                                       pos_y += fontsize_y * CENTERPRINT_SPACING/2;
+                               if (!autocvar_hud_panel_centerprint_flip && pos_y > panel_pos_y + panel_size_y - fontsize_y) // check if the next line can be shown
                                {
                                        drawfontscale = '1 1 0';
                                        return;
                                }
                        }
                }
+               msg_size = pos_y - msg_size;
                if (autocvar_hud_panel_centerprint_flip)
                {
-                       pos_y = next_msg_pos_y;
+                       pos_y = current_msg_pos_y - CENTERPRINT_SPACING * fontsize_y;
                        if (a < 1 && centerprint_msgID[j] == 0) // messages with id can be replaced just after they are faded out, so never move over them the next messages
-                               pos_y += 1.5 * fontsize_y * (1 - a*a);
+                               pos_y += (msg_size + CENTERPRINT_SPACING * fontsize_y) * (1 - sqrt(a));
                }
                else
                {
+                       pos_y += CENTERPRINT_SPACING * fontsize_y;
                        if (a < 1 && centerprint_msgID[j] == 0) // messages with id can be replaced just after they are faded out, so never move over them the next messages
-                               pos_y -= 1.5 * fontsize_y * (1 - a*a);
+                               pos_y -= (msg_size + CENTERPRINT_SPACING * fontsize_y) * (1 - sqrt(a));
                }
-               drawfontscale = '1 1 0';
+       }
+       drawfontscale = '1 1 0';
+       if (n == -1)
+       {
+               centerprint_showing = FALSE;
+               reset_centerprint_messages();
        }
 }
 
@@ -4752,9 +4842,6 @@ void HUD_Main (void)
        if(autocvar__con_chat_maximized)
                HUD_Chat(); // HUD_DrawPanel(HUD_PANEL_CHAT);
 
-       if (autocvar__hud_configure && spectatee_status && hud_configure_prev == -1) // try to join if we are in hud_configure mode, but still spectating, and in the first frame (in order to get rid of motd when launching a server via the menu "HUD Setup" button)
-               localcmd("cmd selectteam auto; cmd join\n");
-
        if(autocvar__hud_configure && tab_panel != -1)
        {
                HUD_Panel_UpdatePosSizeForId(tab_panel)