]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/hud.qc
Objectify nades
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud.qc
index cff29ca8c2a07c6803eeed3e5a3fd9979284cfb3..22687f1caea19830c58562f4214effd85b0db2f6 100644 (file)
@@ -162,7 +162,7 @@ float HUD_GetRowCount(int item_count, vector size, float item_aspect)
        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;
@@ -507,7 +507,8 @@ void HUD_Weapons(void)
        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)
        {
@@ -599,7 +600,7 @@ void HUD_Weapons(void)
                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;
@@ -759,7 +760,7 @@ void HUD_Weapons(void)
 
        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;
@@ -977,8 +978,8 @@ void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expan
        float bonusNades    = getstatf(STAT_NADE_BONUS);
        float bonusProgress = getstatf(STAT_NADE_BONUS_SCORE);
        float bonusType     = getstati(STAT_NADE_BONUS_TYPE);
-       vector nadeColor    = Nade_Color(bonusType);
-       string nadeIcon     = Nade_Icon(bonusType);
+       vector nadeColor    = NADES[bonusType].m_color;
+       string nadeIcon     = NADES[bonusType].m_icon;
 
        vector iconPos, textPos;
 
@@ -1084,6 +1085,7 @@ int nade_prevframe;
 float nade_statuschange_time;
 void HUD_Ammo(void)
 {
+       if(intermission == 2) return;
        if(hud != HUD_NORMAL) return;
        if(!autocvar__hud_configure)
        {
@@ -1358,6 +1360,8 @@ int getPowerupItemAlign(int align, int column, int row, int columns, int rows, b
 
 void HUD_Powerups(void)
 {
+       if(intermission == 2) return;
+
        int allItems = getstati(STAT_ITEMS, 0, 24);
        int allBuffs = getstati(STAT_BUFFS, 0, 24);
        int strengthTime, shieldTime, superTime;
@@ -1522,6 +1526,7 @@ void HUD_Powerups(void)
 void HUD_HealthArmor(void)
 {
        int armor, health, fuel;
+       if(intermission == 2) return;
        if(!autocvar__hud_configure)
        {
                if(!autocvar_hud_panel_healtharmor) return;
@@ -1828,6 +1833,7 @@ void HUD_Notify_Push(string icon, string attacker, string victim)
 
 void HUD_Notify(void)
 {
+       if(intermission == 2) return;
        if (!autocvar__hud_configure)
                if (!autocvar_hud_panel_notify)
                        return;
@@ -1953,6 +1959,7 @@ string seconds_tostring(float sec)
 
 void HUD_Timer(void)
 {
+       if(intermission == 2) return;
        if(!autocvar__hud_configure)
        {
                if(!autocvar_hud_panel_timer) return;
@@ -2012,6 +2019,7 @@ void HUD_Timer(void)
 //
 void HUD_Radar(void)
 {
+       if(intermission == 2) return;
        if (!autocvar__hud_configure)
        {
                if (hud_panel_radar_maximized)
@@ -2323,6 +2331,7 @@ void HUD_Score_Rankings(vector pos, vector mySize, entity me)
 
 void HUD_Score(void)
 {
+       if(intermission == 2) return;
        if(!autocvar__hud_configure)
        {
                if(!autocvar_hud_panel_score) return;
@@ -2506,6 +2515,7 @@ void HUD_Score(void)
 //
 void HUD_RaceTimer (void)
 {
+       if(intermission == 2) return;
        if(!autocvar__hud_configure)
        {
                if(!autocvar_hud_panel_racetimer) return;
@@ -2656,6 +2666,7 @@ void HUD_RaceTimer (void)
 
 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;
@@ -3532,6 +3543,7 @@ float mod_change; // "time" when mod_active changed
 
 void HUD_ModIcons(void)
 {
+       if(intermission == 2) return;
        if(!autocvar__hud_configure)
        {
                if(!autocvar_hud_panel_modicons) return;
@@ -3573,6 +3585,7 @@ void HUD_ModIcons(void)
 //
 void HUD_PressedKeys(void)
 {
+       if(intermission == 2) return;
        if(!autocvar__hud_configure)
        {
                if(!autocvar_hud_panel_pressedkeys) return;
@@ -3659,6 +3672,15 @@ void HUD_Chat(void)
 
        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;
@@ -3727,6 +3749,7 @@ float frametimeavg1; // 1 frame ago
 float frametimeavg2; // 2 frames ago
 void HUD_EngineInfo(void)
 {
+       //if(intermission == 2) return;
        if(!autocvar__hud_configure)
        {
                if(!autocvar_hud_panel_engineinfo) return;
@@ -3788,6 +3811,7 @@ void HUD_EngineInfo(void)
 } while(0)
 void HUD_InfoMessages(void)
 {
+       if(intermission == 2) return;
        if(!autocvar__hud_configure)
        {
                if(!autocvar_hud_panel_infomessages) return;
@@ -3969,6 +3993,7 @@ float acc_prevtime, acc_avg, top_speed, top_speed_time;
 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;
@@ -4360,6 +4385,7 @@ void reset_centerprint_messages(void)
 float hud_configure_cp_generation_time;
 void HUD_CenterPrint (void)
 {
+       if(intermission == 2) return;
        if(!autocvar__hud_configure)
        {
                if(!autocvar_hud_panel_centerprint) return;
@@ -4578,70 +4604,249 @@ void HUD_CenterPrint (void)
        }
 }
 
-// Buffs (#18)
+// ItemsTime (#XX)
 //
-void HUD_Buffs(void)
+const float ITEMSTIME_MAXITEMS = 10;
+float ItemsTime_time[ITEMSTIME_MAXITEMS];
+float ItemsTime_availableTime[ITEMSTIME_MAXITEMS];
+string GetItemsTimePicture(float i)
 {
-       int buffs = getstati(STAT_BUFFS, 0, 24);
-       if(!autocvar__hud_configure)
+       switch(i)
        {
-               if(!autocvar_hud_panel_buffs) return;
-               if(spectatee_status == -1) return;
-               if(getstati(STAT_HEALTH) <= 0) return;
-               if(!buffs) return;
+               case 0: return "item_large_armor";
+               case 1: return "item_mega_health";
+               case 2: return "item_strength";
+               case 3: return "item_shield";
+               case 4: return "item_mega_health";
+               case 5: return "item_strength";
+               case 6: return "item_shield";
+               case 7: return "fuelregen";
+               case 8: return "jetpack";
+               case 9: return "superweapons";
+               default: return "";
+       }
+}
+
+void DrawItemsTimeItem(vector myPos, vector mySize, float ar, float itemcode, float item_time, bool item_available, float item_availableTime)
+{
+       float t = 0;
+       vector color = '0 0 0';
+       float picalpha;
+
+       if(autocvar_hud_panel_itemstime_hidespawned == 2)
+               picalpha = 1;
+       else if(item_available)
+       {
+               float BLINK_FACTOR = 0.15;
+               float BLINK_BASE = 0.85;
+               float BLINK_FREQ = 5;
+               picalpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
+       }
+       else
+               picalpha = 0.3;
+       t = floor(item_time - time + 0.999);
+       if(t < 5)
+               color = '0.7 0 0';
+       else if(t < 10)
+               color = '0.7 0.7 0';
+       else
+               color = '1 1 1';
+
+       vector picpos, numpos;
+       if(autocvar_hud_panel_itemstime_iconalign)
+       {
+               numpos = myPos;
+               picpos = myPos + eX * (ar - 1) * mySize_y;
        }
        else
        {
-               buffs = Buff_Type_first.items; // force first buff
+               numpos = myPos + eX * mySize_y;
+               picpos = myPos;
        }
 
-       int b = 0; // counter to tell other functions that we have buffs
-       entity e;
-       string s = "";
-       for(e = Buff_Type_first; e; e = e.enemy) if(buffs & e.items)
+       if(t > 0 && autocvar_hud_panel_itemstime_progressbar)
        {
-               ++b;
-               string o = strcat(rgb_to_hexcolor(Buff_Color(e.items)), Buff_PrettyName(e.items));
-               if(s == "")
-                       s = o;
+               vector p_pos, p_size;
+               if(autocvar_hud_panel_itemstime_progressbar_reduced)
+               {
+                       p_pos = numpos;
+                       p_size = eX * ((ar - 1)/ar) * mySize_x + eY * mySize_y;
+               }
                else
-                       s = strcat(s, " ", o);
+               {
+                       p_pos = myPos;
+                       p_size = mySize;
+               }
+               HUD_Panel_DrawProgressBar(p_pos, p_size, autocvar_hud_panel_itemstime_progressbar_name, t/autocvar_hud_panel_itemstime_progressbar_maxtime, 0, autocvar_hud_panel_itemstime_iconalign, color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
        }
 
-       HUD_Panel_UpdateCvars();
+       if(t > 0 && autocvar_hud_panel_itemstime_text)
+               drawstring_aspect(numpos, ftos(t), eX * ((ar - 1)/ar) * mySize_x + eY * mySize_y, color, panel_fg_alpha, DRAWFLAG_NORMAL);
+       else
+               picpos.x = myPos.x + mySize.x / 2 - mySize.y / 2;
+       if(item_availableTime)
+               drawpic_aspect_skin_expanding(picpos, GetItemsTimePicture(itemcode), '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * picalpha, DRAWFLAG_NORMAL, item_availableTime);
+       drawpic_aspect_skin(picpos, GetItemsTimePicture(itemcode), '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * picalpha, DRAWFLAG_NORMAL);
+}
+
+void HUD_ItemsTime(void)
+{
+       if(!autocvar__hud_configure)
+       {
+               if(!(
+                       (autocvar_hud_panel_itemstime == 1 && spectatee_status != 0)
+               ||      (autocvar_hud_panel_itemstime == 2 && (spectatee_status != 0 || warmup_stage))
+                       )) { return; }
+
+               ItemsTime_time[0] = getstatf(STAT_ARMOR_LARGE_TIME);
+               ItemsTime_time[1] = getstatf(STAT_HEALTH_MEGA_TIME);
+               ItemsTime_time[2] = getstatf(STAT_INVISIBLE_TIME);
+               ItemsTime_time[3] = getstatf(STAT_SPEED_TIME);
+               ItemsTime_time[4] = getstatf(STAT_EXTRALIFE_TIME);
+               ItemsTime_time[5] = getstatf(STAT_STRENGTH_TIME);
+               ItemsTime_time[6] = getstatf(STAT_SHIELD_TIME);
+               ItemsTime_time[7] = getstatf(STAT_FUELREGEN_TIME);
+               ItemsTime_time[8] = getstatf(STAT_JETPACK_TIME);
+               ItemsTime_time[9] = getstatf(STAT_SUPERWEAPONS_TIME);
+       }
+       else
+       {
+               // do not show here mutator-dependent items
+               ItemsTime_time[0] = time + 0;
+               ItemsTime_time[1] = time + 8;
+               ItemsTime_time[2] = -1; // mutator-dependent
+               ItemsTime_time[3] = -1; // mutator-dependent
+               ItemsTime_time[4] = -1; // mutator-dependent
+               ItemsTime_time[5] = time + 0;
+               ItemsTime_time[6] = time + 4;
+               ItemsTime_time[7] = time + 49;
+               ItemsTime_time[8] = -1;
+               ItemsTime_time[9] = time + 28;
+       }
+
+       float i;
+       float count = 0;
+       if(autocvar_hud_panel_itemstime_hidespawned == 1)
+               for (i = 0; i < ITEMSTIME_MAXITEMS; ++i)
+                       count += (ItemsTime_time[i] > time || -ItemsTime_time[i] > time);
+       else if(autocvar_hud_panel_itemstime_hidespawned == 2)
+               for (i = 0; i < ITEMSTIME_MAXITEMS; ++i)
+                       count += (ItemsTime_time[i] > time);
+       else
+               for (i = 0; i < ITEMSTIME_MAXITEMS; ++i)
+                       count += (ItemsTime_time[i] != -1);
+       if (count == 0)
+               return;
 
+       HUD_Panel_UpdateCvars();
 
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
 
-       HUD_Panel_DrawBg(bound(0, b, 1));
        if(panel_bg_padding)
        {
                pos += '1 1 0' * panel_bg_padding;
                mySize -= '2 2 0' * panel_bg_padding;
        }
 
-       //float panel_ar = mySize_x/mySize_y;
-       //bool is_vertical = (panel_ar < 1);
-       //float buff_iconalign = autocvar_hud_panel_buffs_iconalign;
-       vector buff_offset = '0 0 0';
+       float rows, columns;
+       float ar = max(2, autocvar_hud_panel_itemstime_ratio) + 1;
+       rows = HUD_GetRowCount(count, mySize, ar);
+       columns = ceil(count/rows);
 
-       draw_beginBoldFont();
-       float buff_time, buff_maxtime;
-       buff_time = bound(0, getstatf(STAT_BUFF_TIME) - time, 99);
-       buff_maxtime = 60; // TODO: stat?
-       for(e = Buff_Type_first; e; e = e.enemy) if(buffs & e.items)
+       vector itemstime_size = eX * mySize.x*(1/columns) + eY * mySize.y*(1/rows);
+
+       vector offset = '0 0 0';
+       float newSize;
+       if(autocvar_hud_panel_itemstime_dynamicsize)
        {
-               if(buff_time && autocvar_hud_panel_buffs_progressbar)
-                       HUD_Panel_DrawProgressBar(pos + buff_offset, mySize, autocvar_hud_panel_buffs_progressbar_name, buff_time/buff_maxtime, 0, 0,
-                                                                         Buff_Color(e.items) * -1 + '1 1 1', (autocvar_hud_progressbar_alpha * panel_fg_alpha) * 0.4, DRAWFLAG_NORMAL);
+               if(autocvar__hud_configure)
+               if(menu_enabled != 2)
+                       HUD_Panel_DrawBg(1); // also draw the bg of the entire panel
 
-               //DrawNumIcon(pos + buff_offset, mySize, shield, "shield", is_vertical, buff_iconalign, '1 1 1', 1);
-               drawcolorcodedstring_aspect(pos + buff_offset, s, mySize, panel_fg_alpha * 0.5, DRAWFLAG_NORMAL);
+               // reduce panel to avoid spacing items
+               if(itemstime_size.x / itemstime_size.y < ar)
+               {
+                       newSize = rows * itemstime_size.x / ar;
+                       pos.y += (mySize.y - newSize) / 2;
+                       mySize.y = newSize;
+                       itemstime_size.y = mySize.y / rows;
+               }
+               else
+               {
+                       newSize = columns * itemstime_size.y * ar;
+                       pos.x += (mySize.x - newSize) / 2;
+                       mySize.x = newSize;
+                       itemstime_size.x = mySize.x / columns;
+               }
+               panel_pos = pos - '1 1 0' * panel_bg_padding;
+               panel_size = mySize + '2 2 0' * panel_bg_padding;
+       }
+       else
+       {
+               if(itemstime_size.x/itemstime_size.y > ar)
+               {
+                       newSize = ar * itemstime_size.y;
+                       offset.x = itemstime_size.x - newSize;
+                       pos.x += offset.x/2;
+                       itemstime_size.x = newSize;
+               }
+               else
+               {
+                       newSize = 1/ar * itemstime_size.x;
+                       offset.y = itemstime_size.y - newSize;
+                       pos.y += offset.y/2;
+                       itemstime_size.y = newSize;
+               }
        }
 
-       draw_endBoldFont();
+       HUD_Panel_DrawBg(1);
+
+       float row = 0, column = 0;
+       bool item_available;
+       for (i = 0; i < ITEMSTIME_MAXITEMS; ++i) {
+               if (ItemsTime_time[i] == -1)
+                       continue;
+
+               float item_time = ItemsTime_time[i];
+               if(item_time < -1)
+               {
+                       item_available = true;
+                       item_time = -item_time;
+               }
+               else
+                       item_available = (item_time <= time);
+
+               if(ItemsTime_time[i] >= 0)
+               {
+                       if(time <= ItemsTime_time[i])
+                               ItemsTime_availableTime[i] = 0;
+                       else if(ItemsTime_availableTime[i] == 0)
+                               ItemsTime_availableTime[i] = time;
+               }
+               else if(ItemsTime_availableTime[i] == 0)
+                       ItemsTime_availableTime[i] = time;
+
+               float f = (time - ItemsTime_availableTime[i]) * 2;
+               f = (f > 1) ? 0 : bound(0, f, 1);
+
+               if(autocvar_hud_panel_itemstime_hidespawned == 1)
+                       if(!(ItemsTime_time[i] > time || -ItemsTime_time[i] > time))
+                               continue;
+
+               if(autocvar_hud_panel_itemstime_hidespawned == 2)
+                       if(!(ItemsTime_time[i] > time))
+                               continue;
+
+               DrawItemsTimeItem(pos + eX * column * (itemstime_size.x + offset.x) + eY * row * (itemstime_size.y + offset.y), itemstime_size, ar, i, item_time, item_available, f);
+               ++row;
+               if(row >= rows)
+               {
+                       row = 0;
+                       column = column + 1;
+               }
+       }
 }
 
 
@@ -4672,9 +4877,6 @@ void HUD_Main (void)
 
        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)
@@ -4781,7 +4983,7 @@ void HUD_Main (void)
        }
 
        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();