]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/hud.qc
Merge remote branch 'origin/fruitiex/fruitbalance'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud.qc
index 819dcabc74fcdd146b0272be4ecf5df165178a57..6b21f86a4f281179cdcf8e65807908d0a832fb5c 100644 (file)
@@ -517,7 +517,7 @@ void HUD_Panel_ExportCfg(string cfgname)
                        }
                        fputs(fh, "\n");
                }
-               fputs(fh, strcat("menu_restart", "\n")); // force a menu update when execing config, so that the dialogs are updated
+               fputs(fh, strcat("menu_sync", "\n")); // force the menu to reread the cvars, so that the dialogs are updated
 
                print("^2Successfully exported to hud_", autocvar_hud_skin, "_", cfgname, ".cfg! (Note: It's saved in data/data/)\n");
        }
@@ -1095,17 +1095,29 @@ float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
                        if (bInputType == 1)
                                return true;
 
-                       if (highlightedPanel_copied != -1 && highlightedPanel_prev != -1)
-                       {
-                               // backup first!
-                               panel_pos_backup = panel_pos;
-                               panel_size_backup = panel_size;
-                               highlightedPanel_backup = highlightedPanel_prev;
+                       if (highlightedPanel_copied == -1 || highlightedPanel_prev == -1)
+                               return true;
 
-                               string s;
-                               s = strcat(ftos(panel_size_copied_x/vid_conwidth), " ", ftos(panel_size_copied_y/vid_conheight));
-                               cvar_set(strcat("hud_panel_", panel_name, "_size"), s);
-                       }
+                       HUD_Panel_UpdatePosSizeForId(highlightedPanel_prev)
+
+                       // reduce size if it'd go beyond screen boundaries
+                       vector tmp_size = panel_size_copied;
+                       if (panel_pos_x + panel_size_copied_x > vid_conwidth)
+                               tmp_size_x = vid_conwidth - panel_pos_x;
+                       if (panel_pos_y + panel_size_copied_y > vid_conheight)
+                               tmp_size_y = vid_conheight - panel_pos_y;
+
+                       if (panel_size == tmp_size)
+                               return true;
+
+                       // backup first!
+                       panel_pos_backup = panel_pos;
+                       panel_size_backup = panel_size;
+                       highlightedPanel_backup = highlightedPanel_prev;
+
+                       string s;
+                       s = strcat(ftos(tmp_size_x/vid_conwidth), " ", ftos(tmp_size_y/vid_conheight));
+                       cvar_set(strcat("hud_panel_", panel_name, "_size"), s);
                }
                else if(nPrimary == 'z') // undo last action
                {
@@ -1306,7 +1318,7 @@ void HUD_Panel_Highlight()
 }
 
 float highlightcheck;
-float would_backup;
+vector prev_pos, prev_size;
 void HUD_Panel_Mouse()
 {
        // TODO: needs better check... is there any float that contains the current state of the menu? _menu_alpha isn't apparently updated the frame the menu gets enabled
@@ -1335,22 +1347,29 @@ void HUD_Panel_Mouse()
 
        if(mouseClicked)
        {
-               vector prev_pos, prev_size;
                if(prevMouseClicked == 0)
                {
                        HUD_Panel_Highlight(); // sets highlightedPanel, highlightedAction, panel_click_distance, panel_click_resizeorigin
                                                                        // and calls HUD_Panel_UpdatePosSizeForId() for the highlighted panel
-                       would_backup = TRUE;
-               }
-               else if (would_backup)
-               {
-                       // this is not the actual backup! Saving pos and size values
-                       // only to check later if they are different from new values
                        prev_pos = panel_pos;
                        prev_size = panel_size;
                }
+               else
+                       HUD_Panel_UpdatePosSizeForId(highlightedPanel)
 
-               hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions);
+               if (prev_pos != panel_pos || prev_size != panel_size)
+               {
+                       hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions);
+                       // backup!
+                       panel_pos_backup = prev_pos;
+                       panel_size_backup = prev_size;
+                       highlightedPanel_backup = highlightedPanel;
+               }
+               else
+                       // in case the clicked panel is inside another panel and we aren't
+                       // moving it, avoid the immediate "fix" of its position/size
+                       // (often unwanted and hateful) by disabling collisions check
+                       hud_configure_checkcollisions = false;
 
                if(highlightedAction == 1)
                        HUD_Panel_SetPos(mousepos - panel_click_distance);
@@ -1373,18 +1392,6 @@ void HUD_Panel_Mouse()
                        HUD_Panel_SetPosSize(mySize);
                }
 
-               HUD_Panel_UpdatePosSizeForId(highlightedPanel)
-               if (prevMouseClicked)
-               if (would_backup)
-               if (prev_pos != panel_pos || prev_size != panel_size)
-               {
-                       // backup!
-                       panel_pos_backup = prev_pos;
-                       panel_size_backup = prev_size;
-                       highlightedPanel_backup = highlightedPanel;
-                       would_backup = FALSE;
-               }
-
                // doubleclick check
                if(time - prevMouseClickedTime < 0.4 && prevMouseClicked == 0 && prevMouseClickedPos == mousepos && highlightedPanel >= 0)
                {
@@ -1471,6 +1478,7 @@ float GetAmmoTypeForWep(float i)
                case WEP_UZI: return 1;
                case WEP_CAMPINGRIFLE: return 1;
                case WEP_GRENADE_LAUNCHER: return 2;
+               case WEP_MINE_LAYER: return 2;
                case WEP_ELECTRO: return 3;
                case WEP_CRYLINK: return 3;
                case WEP_HLAC: return 3;
@@ -2248,12 +2256,10 @@ void HUD_HealthArmor(void)
                mySize -= '2 2 0' * panel_bg_padding;
        }
 
-       float armor, health;
+       float armor, health, fuel;
        armor = getstati(STAT_ARMOR);
        health = getstati(STAT_HEALTH);
-
-       float fuel;
-       fuel = getstati(GetAmmoStat(4)); // how much fuel do we have?
+       fuel = getstati(STAT_FUEL);
 
        if(autocvar__hud_configure)
        {
@@ -2577,7 +2583,7 @@ void HUD_KillNotify_Push(string attacker, string victim, float actiontype, float
        killnotify_victims[0] = strzone(victim);
 }
 
-void HUD_KillNotify(string s1, string s2, string s3, float type, float msg)
+void HUD_KillNotify(string s1, string s2, string s3, float type, float msg) // s1 = attacker, s2 = victim
 {
        float w;
        float alsoprint, gentle;
@@ -2658,101 +2664,104 @@ void HUD_KillNotify(string s1, string s2, string s3, float type, float msg)
                }
                else if(type == KILL_FIRST_BLOOD)
                        print("^1",s1, "^1 drew first blood", "\n");
-               // TODO: icon!
                else if (type == DEATH_TELEFRAG) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_TELEFRAG);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_TELEFRAG);
                        if(gentle)
-                               print ("^1",s1, "^1 tried to occupy ", s2, "^1's teleport destination space\n");
+                               print ("^1",s2, "^1 tried to occupy ", s1, "^1's teleport destination space\n");
                        else
-                               print ("^1",s1, "^1 was telefragged by ", s2, "\n");
+                               print ("^1",s2, "^1 was telefragged by ", s1, "\n");
                }
                else if (type == DEATH_DROWN) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_DROWN);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_DROWN);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was drowned by ", s2, "\n");
+                               print ("^1",s2, "^1 was drowned by ", s1, "\n");
                }
                else if (type == DEATH_SLIME) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_SLIME);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_SLIME);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was slimed by ", s2, "\n");
+                               print ("^1",s2, "^1 was slimed by ", s1, "\n");
                }
                else if (type == DEATH_LAVA) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_LAVA);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_LAVA);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was cooked by ", s2, "\n");
+                               print ("^1",s2, "^1 was cooked by ", s1, "\n");
                }
                else if (type == DEATH_FALL) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_FALL);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_FALL);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was grounded by ", s2, "\n");
+                               print ("^1",s2, "^1 was grounded by ", s1, "\n");
                }
                else if (type == DEATH_SHOOTING_STAR) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_SHOOTING_STAR);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_SHOOTING_STAR);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was shot into space by ", s2, "\n");
+                               print ("^1",s2, "^1 was shot into space by ", s1, "\n");
                }
                else if (type == DEATH_SWAMP) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was conserved by ", s2, "\n");
+                               print ("^1",s2, "^1 was conserved by ", s1, "\n");
                }
                else if (type == DEATH_HURTTRIGGER)
                {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_HURTTRIGGER);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_HURTTRIGGER);
                        if(alsoprint)
-                               print("^1",s1, "^1 was thrown into a world of hurt by ", s2, "\n");
+                               print("^1",s2, "^1 was thrown into a world of hurt by ", s1, "\n");
                } else if(type == DEATH_SBCRUSH) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was crushed by ^1", s2, "\n");
+                               print ("^1",s2, "^1 was crushed by ^1", s1, "\n");
                } else if(type == DEATH_SBMINIGUN) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 got shredded by ^1", s2, "\n");
+                               print ("^1",s2, "^1 got shredded by ^1", s1, "\n");
                } else if(type == DEATH_SBROCKET) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was blased to bits by ^1", s2, "\n");
+                               print ("^1",s2, "^1 was blased to bits by ^1", s1, "\n");
                } else if(type == DEATH_SBBLOWUP) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 got caught in the destruction of ^1", s2, "'s vehicle\n");
+                               print ("^1",s2, "^1 got caught in the destruction of ^1", s1, "'s vehicle\n");
                } else if(type == DEATH_WAKIGUN) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was bolted down by ^1", s2, "\n");
+                               print ("^1",s2, "^1 was bolted down by ^1", s1, "\n");
                } else if(type == DEATH_WAKIROCKET) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 could find no shelter from ^1", s2, "'s rockets\n");
+                               print ("^1",s2, "^1 could find no shelter from ^1", s1, "'s rockets\n");
                } else if(type == DEATH_WAKIBLOWUP) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 dies when ^1", s2, "'s wakizashi dies.\n");
+                               print ("^1",s2, "^1 dies when ^1", s1, "'s wakizashi dies.\n");
                } else if(type == DEATH_TURRET) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was pushed into the line of fire by ^1", s2, "\n");
+                               print ("^1",s2, "^1 was pushed into the line of fire by ^1", s1, "\n");
                } else if(type == DEATH_TOUCHEXPLODE) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was pushed into an accident by ^1", s2, "\n");
+                               print ("^1",s2, "^1 was pushed into an accident by ^1", s1, "\n");
                } else if(type == DEATH_CHEAT) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was unfairly eliminated by ^1", s2, "\n");
+                               print ("^1",s2, "^1 was unfairly eliminated by ^1", s1, "\n");
                } else if (type == DEATH_FIRE) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was burnt to death by ^1", s2, "\n");
+                               print ("^1",s2, "^1 was burnt to death by ^1", s1, "\n");
                } else if (type == DEATH_CUSTOM) {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_CUSTOM);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_CUSTOM);
+                       if(alsoprint)
+                               print("^1", sprintf(s3, strcat(s2, "^1"), strcat(s1, "^1")), "\n");
+               } else if (type == DEATH_HURTTRIGGER) {
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_HURTTRIGGER);
                        if(alsoprint)
-                               print ("^1",s1, "^1 ", s2, "\n");
+                               print("^1", sprintf(s3, strcat(s2, "^1"), strcat(s1, "^1")), "\n");
                } else {
-                       HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC);
+                       HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was fragged by ", s2, "\n");
+                               print ("^1",s2, "^1 was fragged by ", s1, "\n");
                }
        } else if(msg == MSG_SPREE) {
                if(type == KILL_END_SPREE) {
@@ -2853,11 +2862,11 @@ void HUD_KillNotify(string s1, string s2, string s3, float type, float msg)
                } else if (type == DEATH_CUSTOM) {
                        HUD_KillNotify_Push(s1, "", 0, DEATH_CUSTOM);
                        if(alsoprint)
-                               print ("^1",s1, "^1 ", s2, "\n");
+                               print("^1", sprintf(s2, strcat(s1, "^1")), "\n");
                } else if (type == DEATH_HURTTRIGGER) {
                        HUD_KillNotify_Push(s1, "", 0, DEATH_HURTTRIGGER);
                        if(alsoprint)
-                               print ("^1",s1, "^1 was in the wrong place\n");
+                               print("^1", sprintf(s2, strcat(s1, "^1")), "\n");
                } else if(type == DEATH_TOUCHEXPLODE) {
                        HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
                        if(alsoprint)
@@ -3742,6 +3751,17 @@ void HUD_VoteWindow(void)
        pos = panel_pos;
        mySize = panel_size;
 
+       if(!autocvar__hud_configure)
+       {
+               panel_fg_alpha = autocvar_hud_panel_fg_alpha;
+               panel_bg_alpha_str = autocvar_hud_panel_vote_bg_alpha;
+
+               if(panel_bg_alpha_str == "") {
+                       panel_bg_alpha_str = ftos(autocvar_hud_panel_bg_alpha);
+               }
+               panel_bg_alpha = stof(panel_bg_alpha_str);
+       }
+
        string s;
        float a;
        if(vote_active != vote_prev) {
@@ -3764,9 +3784,9 @@ void HUD_VoteWindow(void)
        if(!vote_alpha)
                return;
 
-       a = vote_alpha * bound(autocvar_hud_panel_vote_alreadyvoted_alpha, 1 - vote_highlighted, 1);
-
+       a = panel_bg_alpha * vote_alpha * bound(autocvar_hud_panel_vote_alreadyvoted_alpha, 1 - vote_highlighted, 1);
        HUD_Panel_DrawBg(a);
+       a = panel_fg_alpha * vote_alpha * bound(autocvar_hud_panel_vote_alreadyvoted_alpha, 1 - vote_highlighted, 1);
        if(panel_bg_padding)
        {
                pos += '1 1 0' * panel_bg_padding;
@@ -3792,37 +3812,37 @@ void HUD_VoteWindow(void)
        mySize = newSize;
 
        s = "A vote has been called for:";
-       drawstring_aspect(pos, s, eX * mySize_x + eY * (2/8) * mySize_y, '1 1 1', a * panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawstring_aspect(pos, s, eX * mySize_x + eY * (2/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL);
        s = textShortenToWidth(vote_called_vote, mySize_x, '1 1 0' * mySize_y * (1.75/8), stringwidth_colors);
        if(autocvar__hud_configure)
                s = "^1Configure the HUD";
-       drawcolorcodedstring_aspect(pos + eY * (2/8) * mySize_y, s, eX * mySize_x + eY * (1.75/8) * mySize_y, a * panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawcolorcodedstring_aspect(pos + eY * (2/8) * mySize_y, s, eX * mySize_x + eY * (1.75/8) * mySize_y, a, DRAWFLAG_NORMAL);
 
        // print the yes/no counts
-       s = strcat("Yes (", getcommandkey("not bound", "vyes"), "): ", ftos(vote_yescount));
-       drawstring_aspect(pos + eY * (4/8) * mySize_y, s, eX * 0.5 * mySize_x + eY * (1.5/8) * mySize_y, '0 1 0', a * panel_fg_alpha, DRAWFLAG_NORMAL);
-       s = strcat("No (", getcommandkey("not bound", "vno"), "): ", ftos(vote_nocount));
-       drawstring_aspect(pos + eX * 0.5 * mySize_x + eY * (4/8) * mySize_y, s, eX * 0.5 * mySize_x + eY * (1.5/8) * mySize_y, '1 0 0', a * panel_fg_alpha, DRAWFLAG_NORMAL);
+       s = strcat("Yes (", getcommandkey("vyes", "vyes"), "): ", ftos(vote_yescount));
+       drawstring_aspect(pos + eY * (4/8) * mySize_y, s, eX * 0.5 * mySize_x + eY * (1.5/8) * mySize_y, '0 1 0', a, DRAWFLAG_NORMAL);
+       s = strcat("No (", getcommandkey("vno", "vno"), "): ", ftos(vote_nocount));
+       drawstring_aspect(pos + eX * 0.5 * mySize_x + eY * (4/8) * mySize_y, s, eX * 0.5 * mySize_x + eY * (1.5/8) * mySize_y, '1 0 0', a, DRAWFLAG_NORMAL);
 
        // draw the progress bar backgrounds
-       drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_back", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a * panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_back", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL);
 
        // draw the highlights
        if(vote_highlighted == 1) {
                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, '0 1 0', a * panel_fg_alpha, DRAWFLAG_NORMAL);
+               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) {
                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, '0 1 0', a * panel_fg_alpha, DRAWFLAG_NORMAL);
+               drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_voted", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL);
        }
 
        // draw the progress bars
        drawsetcliparea(pos_x, pos_y, mySize_x * 0.5 * (vote_yescount/vote_needed), mySize_y);
-       drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_prog", eX * mySize_x + eY * (3/8) * mySize_y, '0 1 0', a * panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_prog", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL);
 
        drawsetcliparea(pos_x + mySize_x - mySize_x * 0.5 * (vote_nocount/vote_needed), pos_y, mySize_x * 0.5, mySize_y);
-       drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_prog", eX * mySize_x + eY * (3/8) * mySize_y, '1 0 0', a * panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_prog", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL);
 
        drawresetcliparea();
 
@@ -4431,8 +4451,15 @@ void HUD_Chat(void)
        {
                panel_pos_y = panel_bg_border;
                panel_size_y = vid_conheight - panel_bg_border * 2;
-               if(panel_bg == "0")
-                       panel_bg = "border"; // force a border when maximized
+               if(panel_bg == "0") // force a border when maximized
+               {
+                       if(precache_pic(panel_bg) == "") {
+                               panel_bg = strcat(hud_skin_path, "/border_default");
+                               if(precache_pic(panel_bg) == "") {
+                                       panel_bg = "gfx/hud/default/border_default";
+                               }
+                       }
+               }
                panel_bg_alpha = max(0.75, panel_bg_alpha); // force an alpha of at least 0.75
        }
 
@@ -4500,29 +4527,32 @@ void HUD_EngineInfo(void)
                mySize -= '2 2 0' * panel_bg_padding;
        }
 
+       float currentTime = gettime(GETTIME_REALTIME);
        if(cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage"))
        {
-               frametimeavg = (frametimeavg + frametimeavg1 + frametimeavg2 + frametime)/4; // average three frametimes into framecounter for slightly more stable fps readings :P
+               float currentframetime = currentTime - prevfps_time;
+               frametimeavg = (frametimeavg + frametimeavg1 + frametimeavg2 + currentframetime)/4; // average three frametimes into framecounter for slightly more stable fps readings :P
                frametimeavg2 = frametimeavg1;
                frametimeavg1 = frametimeavg;
                
                float weight;
                weight = cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage_new_weight");
-               if(frametime > 0.0001) // filter out insane values which sometimes seem to occur and throw off the average? If you are getting 10,000 fps or more, then you don't need a framerate counter.
+               if(currentframetime > 0.0001) // filter out insane values which sometimes seem to occur and throw off the average? If you are getting 10,000 fps or more, then you don't need a framerate counter.
                {
-                       if(fabs(prevfps - (1/frametimeavg)) > prevfps * cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage_instantupdate_change_threshold")) // if there was a big jump in fps, just force prevfps at current (1/frametime) to make big updates instant
-                               prevfps = (1/frametime);
+                       if(fabs(prevfps - (1/frametimeavg)) > prevfps * cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage_instantupdate_change_threshold")) // if there was a big jump in fps, just force prevfps at current (1/currentframetime) to make big updates instant
+                               prevfps = (1/currentframetime);
                        prevfps = (1 - weight) * prevfps + weight * (1/frametimeavg); // framecounter just used so there's no need for a new variable, think of it as "frametime average"
                }
+               prevfps_time = currentTime;
        }
        else
        {
                framecounter += 1;
-               if(time - prevfps_time > cvar("hud_panel_engineinfo_framecounter_time"))
+               if(currentTime - prevfps_time > cvar("hud_panel_engineinfo_framecounter_time"))
                {
-                       prevfps = framecounter/cvar("hud_panel_engineinfo_framecounter_time");
+                       prevfps = framecounter/(currentTime - prevfps_time);
                        framecounter = 0;
-                       prevfps_time = time;
+                       prevfps_time = currentTime;
                }
        }
 
@@ -4535,6 +4565,11 @@ void HUD_EngineInfo(void)
 
 // Info messages panel (#14)
 //
+#define drawInfoMessage(s)\
+       if(autocvar_hud_panel_infomessages_flip)\
+               o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize);\
+       drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);\
+       o_y += fontsize_y;
 void HUD_InfoMessages(void)
 {
        if(!autocvar_hud_panel_infomessages && !autocvar__hud_configure)
@@ -4593,35 +4628,22 @@ void HUD_InfoMessages(void)
                                s = "^1Observing";
                        else
                                s = strcat("^1Spectating: ^7", GetPlayerName(spectatee_status - 1));
-
-                       if(autocvar_hud_panel_infomessages_flip)
-                               o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-                       drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-                       o += eY * fontsize_y;
+                       drawInfoMessage(s)
 
                        if(spectatee_status == -1)
-                               s = strcat("^1Press ^3", getcommandkey("primary fire", "+attack"), "^1 to spectate");
+                               s = strcat("^1Press ^3", getcommandkey("primary fire", "+fire"), "^1 to spectate");
                        else
-                               s = strcat("^1Press ^3", getcommandkey("primary fire", "+attack"), "^1 for another player");
-                       if(autocvar_hud_panel_infomessages_flip)
-                               o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-                       drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-                       o += eY * fontsize_y;
+                               s = strcat("^1Press ^3", getcommandkey("primary fire", "+fire"), "^1 for another player");
+                       drawInfoMessage(s)
 
                        if(spectatee_status == -1)
                                s = strcat("^1Use ^3", getcommandkey("next weapon", "weapnext"), "^1 or ^3", getcommandkey("previous weapon", "weapprev"), "^1 to change the speed");
                        else
-                               s = strcat("^1Press ^3", getcommandkey("secondary fire", "+attack2"), "^1 to observe");
-                       if(autocvar_hud_panel_infomessages_flip)
-                               o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-                       drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-                       o += eY * fontsize_y;
+                               s = strcat("^1Press ^3", getcommandkey("secondary fire", "+fire2"), "^1 to observe");
+                       drawInfoMessage(s)
 
                        s = strcat("^1Press ^3", getcommandkey("server info", "+show_info"), "^1 for gamemode info");
-                       if(autocvar_hud_panel_infomessages_flip)
-                               o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-                       drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-                       o += eY * fontsize_y;
+                       drawInfoMessage(s)
 
                        if(gametype == GAME_ARENA)
                                s = "^1Wait for your turn to join";
@@ -4638,10 +4660,7 @@ void HUD_InfoMessages(void)
                        }
                        else
                                s = strcat("^1Press ^3", getcommandkey("jump", "+jump"), "^1 to join");
-                       if(autocvar_hud_panel_infomessages_flip)
-                               o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-                       drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-                       o += eY * fontsize_y;
+                       drawInfoMessage(s)
 
                        //show restart countdown:
                        if (time < getstatf(STAT_GAMESTARTTIME)) {
@@ -4650,16 +4669,13 @@ void HUD_InfoMessages(void)
                                countdown = ceil(getstatf(STAT_GAMESTARTTIME) - time);
                                s = strcat("^1Game starts in ^3", ftos(countdown), "^1 seconds");
                                drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-                               o += eY * fontsize_y;
+                               o_y += fontsize_y;
                        }
                }
                if(warmup_stage && !intermission)
                {
                        s = "^2Currently in ^1warmup^2 stage!";
-                       if(autocvar_hud_panel_infomessages_flip)
-                               o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-                       drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-                       o += eY * fontsize_y;
+                       drawInfoMessage(s)
                }
 
                string blinkcolor;
@@ -4684,18 +4700,12 @@ void HUD_InfoMessages(void)
                                else
                                        s = strcat("^2Waiting for others to ready up...");
                        }
-                       if(autocvar_hud_panel_infomessages_flip)
-                               o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-                       drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-                       o += eY * fontsize_y;
+                       drawInfoMessage(s)
                }
                else if(warmup_stage && !intermission && !spectatee_status)
                {
                        s = strcat("^2Press ^3", getcommandkey("ready", "ready"), "^2 to end warmup");
-                       if(autocvar_hud_panel_infomessages_flip)
-                               o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-                       drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-                       o += eY * fontsize_y;
+                       drawInfoMessage(s)
                }
 
                if(teamplay && !intermission && !spectatee_status && gametype != GAME_CA && teamnagger)
@@ -4721,11 +4731,7 @@ void HUD_InfoMessages(void)
                                        if (tm.team != COLOR_SPECTATOR)
                                        if (tm.team_size == ts_max)
                                                s = strcat(s, " Press ^3", getcommandkey("team menu", "menu_showteamselect"), blinkcolor, " to adjust");
-
-                                       if(autocvar_hud_panel_infomessages_flip)
-                                               o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-                                       drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-                                       o += eY * fontsize_y;
+                                       drawInfoMessage(s)
                                }
                        }
                }
@@ -4733,25 +4739,13 @@ void HUD_InfoMessages(void)
        else 
        {
                s = "^7Press ^3ESC ^7to show HUD options.";
-               if(autocvar_hud_panel_infomessages_flip)
-                       o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-               drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-               o += eY * fontsize_y;
+               drawInfoMessage(s)
                s = "^3Doubleclick ^7a panel for panel-specific options.";
-               if(autocvar_hud_panel_infomessages_flip)
-                       o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-               drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-               o += eY * fontsize_y;
+               drawInfoMessage(s)
                s = "^3CTRL ^7to disable collision testing, ^3SHIFT ^7and";
-               if(autocvar_hud_panel_infomessages_flip)
-                       o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-               drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-               o += eY * fontsize_y;
+               drawInfoMessage(s)
                s = "^3ALT ^7+ ^3ARROW KEYS ^7for fine adjustments.";
-               if(autocvar_hud_panel_infomessages_flip)
-                       o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
-               drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
-               o += eY * fontsize_y;
+               drawInfoMessage(s)
        }
 }
 
@@ -4968,7 +4962,10 @@ void HUD_Main (void)
                string pic;
                pic = strcat(hud_skin_path, "/", autocvar_hud_dock);
                if(precache_pic(pic) == "") {
-                       pic = "gfx/hud/default/dock_medium";
+                       pic = strcat(hud_skin_path, "/dock_medium");
+                       if(precache_pic(pic) == "") {
+                               pic = "gfx/hud/default/dock_medium";
+                       }
                }
                drawpic('0 0 0', pic, eX * vid_conwidth + eY * vid_conheight, color, autocvar_hud_dock_alpha * hud_fade_alpha, DRAWFLAG_NORMAL); // no aspect ratio forcing on dock...
        }