]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/hud.qc
Fix hud_panel_ammo_onlycurrent
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud.qc
index d151a535678400ace2f7465b2a802b3bbdfb3bd6..41805d18edfa57cd195790ef9afbe52aa6c04809 100644 (file)
@@ -142,16 +142,16 @@ float stringwidth_nocolors(string s, vector theSize)
        return stringwidth(s, FALSE, theSize);
 }
 
-void drawstringright(vector position, string text, vector scale, vector rgb, float theAlpha, float flag)
+void drawstringright(vector position, string text, vector theScale, vector rgb, float theAlpha, float flag)
 {
-       position_x -= 2 / 3 * strlen(text) * scale_x;
-       drawstring(position, text, scale, rgb, theAlpha, flag);
+       position_x -= 2 / 3 * strlen(text) * theScale_x;
+       drawstring(position, text, theScale, rgb, theAlpha, flag);
 }
 
-void drawstringcenter(vector position, string text, vector scale, vector rgb, float theAlpha, float flag)
+void drawstringcenter(vector position, string text, vector theScale, vector rgb, float theAlpha, float flag)
 {
-       position_x = 0.5 * (vid_conwidth - 0.6025 * strlen(text) * scale_x);
-       drawstring(position, text, scale, rgb, theAlpha, flag);
+       position_x = 0.5 * (vid_conwidth - 0.6025 * strlen(text) * theScale_x);
+       drawstring(position, text, theScale, rgb, theAlpha, flag);
 }
 
 // return the string of the onscreen race timer
@@ -242,7 +242,7 @@ float GetPlayerColorForce(float i)
 
 float GetPlayerColor(float i)
 {
-       if not(playerslots[i].gotscores) // unconnected
+       if(!playerslots[i].gotscores) // unconnected
                return NUM_SPECTATOR;
        else if(stof(getplayerkeyvalue(i, "frags")) == FRAGS_SPECTATOR)
                return NUM_SPECTATOR;
@@ -408,42 +408,6 @@ float weaponorder_cmp(float i, float j, entity pass)
        return aj - ai; // the string is in REVERSE order (higher prio at the right is what we want, but higher prio first is the string)
 }
 
-float GetAmmoStat(float i)
-{
-       switch(i)
-       {
-               case 0: return STAT_SHELLS;
-               case 1: return STAT_NAILS;
-               case 2: return STAT_ROCKETS;
-               case 3: return STAT_CELLS;
-               case 4: return STAT_FUEL;
-               default: return -1;
-       }
-}
-
-float GetAmmoTypeForWep(float i)
-{
-       switch(i)
-       {
-               case WEP_SHOTGUN: return 0;
-               case WEP_UZI: 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;
-               case WEP_MINSTANEX: return 3;
-               case WEP_NEX: return 3;
-               case WEP_RIFLE: return 1;
-               case WEP_HAGAR: return 2;
-               case WEP_ROCKET_LAUNCHER: return 2;
-               case WEP_SEEKER: return 2;
-               case WEP_FIREBALL: return 4;
-               case WEP_HOOK: return 3;
-               default: return -1;
-       }
-}
-
 void HUD_Weapons(void)
 {
        // declarations
@@ -460,7 +424,7 @@ void HUD_Weapons(void)
        float timein_effect_length = autocvar_hud_panel_weapons_timeout_speed_in; //? 0.375 : 0);
        float timeout_effect_length = autocvar_hud_panel_weapons_timeout_speed_out; //? 0.75 : 0);
 
-       float ammo_type, ammo_full;
+       float ammo_full;
        float barsize_x = 0, barsize_y = 0, baroffset_x = 0, baroffset_y = 0;
        vector ammo_color = '1 0 1';
        float ammo_alpha = 1;
@@ -734,12 +698,12 @@ void HUD_Weapons(void)
 
                // skip this weapon if we don't own it (and onlyowned is enabled)-- or if weapons_complainbubble is showing for this weapon
                if(autocvar_hud_panel_weapons_onlyowned)
-               if not((weapons_stat & WepSet_FromWeapon(self.weapon)) || (self.weapon == complain_weapon))
+               if (!((weapons_stat & WepSet_FromWeapon(self.weapon)) || (self.weapon == complain_weapon)))
                        continue;
 
                // figure out the drawing position of weapon
-               weapon_pos = (panel_pos 
-                       + eX * column * weapon_size_x 
+               weapon_pos = (panel_pos
+                       + eX * column * weapon_size_x
                        + eY * row * weapon_size_y);
 
                // draw background behind currently selected weapon
@@ -761,7 +725,7 @@ void HUD_Weapons(void)
                if(weapons_stat & WepSet_FromWeapon(self.weapon))
                {
                        // draw the weapon image
-                       drawpic_aspect_skin(weapon_pos, strcat("weapon", self.netname), weapon_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+                       drawpic_aspect_skin(weapon_pos, self.model2, weapon_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 
                        // draw weapon label string
                        switch(autocvar_hud_panel_weapons_label)
@@ -775,7 +739,7 @@ void HUD_Weapons(void)
                                        break;
 
                                case 3: // weapon name
-                                       drawstring(weapon_pos, self.netname, '1 1 0' * 0.5 * weapon_size_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+                                       drawstring(weapon_pos, strtolower(self.message), '1 1 0' * 0.5 * weapon_size_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
                                        break;
 
                                default: // nothing
@@ -783,21 +747,19 @@ void HUD_Weapons(void)
                        }
 
                        // draw ammo status bar
-                       if(autocvar_hud_panel_weapons_ammo && self.weapon != WEP_TUBA && self.weapon != WEP_LASER && self.weapon != WEP_PORTO)
+                       if(autocvar_hud_panel_weapons_ammo && (self.ammo_field != ammo_none))
                        {
-                               a = 0;
-                               ammo_type = GetAmmoTypeForWep(self.weapon);
-                               if(ammo_type != -1)
-                                       a = getstati(GetAmmoStat(ammo_type)); // how much ammo do we have?
+                               a = getstati(GetAmmoStat(self.ammo_field)); // how much ammo do we have?
 
                                if(a > 0)
                                {
-                                       switch(ammo_type) {
-                                               case 0: ammo_full = autocvar_hud_panel_weapons_ammo_full_shells; break;
-                                               case 1: ammo_full = autocvar_hud_panel_weapons_ammo_full_nails; break;
-                                               case 2: ammo_full = autocvar_hud_panel_weapons_ammo_full_rockets; break;
-                                               case 3: ammo_full = autocvar_hud_panel_weapons_ammo_full_cells; break;
-                                               case 4: ammo_full = autocvar_hud_panel_weapons_ammo_full_fuel; break;
+                                       switch(self.ammo_field)
+                                       {
+                                               case ammo_shells:  ammo_full = autocvar_hud_panel_weapons_ammo_full_shells;  break;
+                                               case ammo_nails:   ammo_full = autocvar_hud_panel_weapons_ammo_full_nails;   break;
+                                               case ammo_rockets: ammo_full = autocvar_hud_panel_weapons_ammo_full_rockets; break;
+                                               case ammo_cells:   ammo_full = autocvar_hud_panel_weapons_ammo_full_cells;   break;
+                                               case ammo_fuel:    ammo_full = autocvar_hud_panel_weapons_ammo_full_fuel;    break;
                                                default: ammo_full = 60;
                                        }
 
@@ -805,15 +767,25 @@ void HUD_Weapons(void)
                                                weapon_pos_x + baroffset_x,
                                                weapon_pos_y + baroffset_y,
                                                barsize_x * bound(0, a/ammo_full, 1),
-                                               barsize_y);
-                                       drawpic_aspect_skin(weapon_pos, "weapon_ammo", weapon_size, ammo_color, ammo_alpha, DRAWFLAG_NORMAL);
+                                               barsize_y
+                                       );
+
+                                       drawpic_aspect_skin(
+                                               weapon_pos,
+                                               "weapon_ammo",
+                                               weapon_size,
+                                               ammo_color,
+                                               ammo_alpha,
+                                               DRAWFLAG_NORMAL
+                                       );
+
                                        drawresetcliparea();
                                }
                        }
                }
                else // draw a "ghost weapon icon" if you don't have the weapon
                {
-                       drawpic_aspect_skin(weapon_pos, strcat("weapon", self.netname), weapon_size, '0 0 0', panel_fg_alpha * 0.5, DRAWFLAG_NORMAL);
+                       drawpic_aspect_skin(weapon_pos, self.model2, weapon_size, '0 0 0', panel_fg_alpha * 0.5, DRAWFLAG_NORMAL);
                }
 
                // draw the complain message
@@ -855,44 +827,30 @@ void HUD_Weapons(void)
 }
 
 // Ammo (#1)
-//
-// TODO: macro
-float GetAmmoItemCode(float i)
+void DrawAmmoItem(vector myPos, vector mySize, .float ammotype, float currently_selected, float infinite_ammo)
 {
-       switch(i)
+       float a = 0;
+       if(ammotype != ammo_none)
        {
-               case 0: return IT_SHELLS;
-               case 1: return IT_NAILS;
-               case 2: return IT_ROCKETS;
-               case 3: return IT_CELLS;
-               case 4: return IT_FUEL;
-               default: return -1;
-       }
-}
-
-string GetAmmoPicture(float i)
-{
-       switch(i)
-       {
-               case 0: return "ammo_shells";
-               case 1: return "ammo_bullets";
-               case 2: return "ammo_rockets";
-               case 3: return "ammo_cells";
-               case 4: return "ammo_fuel";
-               default: return "";
+               if(autocvar__hud_configure)
+               {
+                       currently_selected = (ammotype == ammo_rockets); //rockets always selected
+                       a = 60;
+               }
+               else
+               {
+                       // how much ammo do we have of this ammotype?
+                       a = getstati(GetAmmoStat(ammotype));
+               }
        }
-}
-
-void DrawAmmoItem(vector myPos, vector mySize, float itemcode, float currently_selected, float infinite_ammo)
-{
-       float a;
-       if(autocvar__hud_configure)
+       else
        {
-               currently_selected = (itemcode == 2); //rockets always selected
-               a = 31 + mod(itemcode*93, 128);
+               #if 0
+               infinite_ammo = TRUE;
+               #else
+               return; // just don't draw infinite ammo at all.
+               #endif
        }
-       else
-               a = getstati(GetAmmoStat(itemcode)); // how much ammo do we have of type itemcode?
 
        vector color;
        if(infinite_ammo)
@@ -920,7 +878,7 @@ void DrawAmmoItem(vector myPos, vector mySize, float itemcode, float currently_s
                picpos = myPos;
        }
 
-       if (currently_selected)
+       if(currently_selected)
                drawpic_aspect_skin(myPos, "ammo_current_bg", mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 
     if(a > 0 && autocvar_hud_panel_ammo_progressbar)
@@ -934,9 +892,9 @@ void DrawAmmoItem(vector myPos, vector mySize, float itemcode, float currently_s
             drawstring_aspect(numpos, ftos(a), eX * (2/3) * mySize_x + eY * mySize_y, '0 0 0', panel_fg_alpha * theAlpha * 0.5, DRAWFLAG_NORMAL);
     }
        if(a > 0 || infinite_ammo)
-               drawpic_aspect_skin(picpos, GetAmmoPicture(itemcode), '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * theAlpha, DRAWFLAG_NORMAL);
+               drawpic_aspect_skin(picpos, GetAmmoPicture(ammotype), '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * theAlpha, DRAWFLAG_NORMAL);
        else // "ghost" ammo icon
-               drawpic_aspect_skin(picpos, GetAmmoPicture(itemcode), '1 1 0' * mySize_y, '0 0 0', panel_fg_alpha * theAlpha * 0.5, DRAWFLAG_NORMAL);
+               drawpic_aspect_skin(picpos, GetAmmoPicture(ammotype), '1 1 0' * mySize_y, '0 0 0', panel_fg_alpha * theAlpha * 0.5, DRAWFLAG_NORMAL);
 }
 
 void HUD_Ammo(void)
@@ -966,7 +924,7 @@ void HUD_Ammo(void)
 
        float rows = 0, columns, row, column;
        vector ammo_size;
-       if (autocvar_hud_panel_ammo_onlycurrent)
+       if(autocvar_hud_panel_ammo_onlycurrent)
                ammo_size = mySize;
        else
        {
@@ -996,38 +954,40 @@ void HUD_Ammo(void)
                ammo_size_y = newSize;
        }
 
-       float i, stat_items, currently_selected, infinite_ammo;
-       infinite_ammo = FALSE;
-       if (autocvar_hud_panel_ammo_onlycurrent)
+       float i;
+       float infinite_ammo = (getstati(STAT_ITEMS, 0, 24) & IT_UNLIMITED_WEAPON_AMMO);
+       if(autocvar_hud_panel_ammo_onlycurrent)
        {
                if(autocvar__hud_configure)
                {
-                       DrawAmmoItem(pos, ammo_size, 2, true, FALSE); //show rockets
+                       DrawAmmoItem(pos, ammo_size, ammo_rockets, TRUE, FALSE);
                }
                else
                {
-                       stat_items = getstati(STAT_ITEMS, 0, 24);
-                       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, infinite_ammo);
-                                       break;
-                               }
-                       }
+                       DrawAmmoItem(
+                               pos,
+                               ammo_size,
+                               (get_weaponinfo(switchweapon)).ammo_field,
+                               TRUE,
+                               infinite_ammo
+                       );
                }
        }
        else
        {
-               stat_items = getstati(STAT_ITEMS, 0, 24);
-               if (stat_items & IT_UNLIMITED_WEAPON_AMMO)
-                       infinite_ammo = TRUE;
+               .float ammotype;
                row = column = 0;
-               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, infinite_ammo);
+               for(i = 0; i < AMMO_COUNT; ++i)
+               {
+                       ammotype = GetAmmoFieldFromNum(i);
+                       DrawAmmoItem(
+                               pos + eX * column * (ammo_size_x + offset_x) + eY * row * (ammo_size_y + offset_y),
+                               ammo_size,
+                               ammotype,
+                               ((get_weaponinfo(switchweapon)).ammo_field == ammotype),
+                               infinite_ammo
+                       );
+
                        ++row;
                        if(row >= rows)
                        {
@@ -1133,7 +1093,7 @@ void HUD_Powerups(void)
        {
                if(!autocvar_hud_panel_powerups) return;
                if(spectatee_status == -1) return;
-               if not(getstati(STAT_ITEMS, 0, 24) & (IT_STRENGTH | IT_INVINCIBLE | IT_SUPERWEAPON)) return;
+               if(!(getstati(STAT_ITEMS, 0, 24) & (IT_STRENGTH | IT_INVINCIBLE | IT_SUPERWEAPON))) return;
                if (getstati(STAT_HEALTH) <= 0) return;
 
                strength_time = bound(0, getstatf(STAT_STRENGTH_FINISHED) - time, 99);
@@ -1416,7 +1376,7 @@ void HUD_HealthArmor(void)
        if(autocvar_hud_panel_healtharmor == 2) // combined health and armor display
        {
                vector v;
-               v = healtharmor_maxdamage(health, armor, armorblockpercent);
+               v = healtharmor_maxdamage(health, armor, armorblockpercent, DEATH_WEAPON);
 
                float x;
                x = floor(v_x + 1);
@@ -1543,7 +1503,7 @@ void HUD_HealthArmor(void)
                                        {
                                                float BLINK_FACTOR = 0.15;
                                                float BLINK_BASE = 0.85;
-                                               float BLINK_FREQ = 9; 
+                                               float BLINK_FREQ = 9;
                                                pain_health_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
                                        }
                                }
@@ -1664,7 +1624,7 @@ void HUD_Notify(void)
        float entries, height;
        entries = bound(1, floor(KN_MAX_ENTRIES * mySize_y/mySize_x), KN_MAX_ENTRIES);
        height = mySize_y/entries;
-       
+
        vector fontsize;
        float fontheight = height * autocvar_hud_panel_notify_fontsize;
        fontsize = '0.5 0.5 0' * fontheight;
@@ -1703,7 +1663,7 @@ void HUD_Notify(void)
                                a = entries - 1 - i;
                        attacker = textShortenToWidth(sprintf(_("Player %d"), a+1), 0.48 * mySize_x - height, fontsize, stringwidth_colors);
                        victim = textShortenToWidth(sprintf(_("Player %d"), a+2), 0.48 * mySize_x - height, fontsize, stringwidth_colors);
-                       icon = strcat("weapon", get_weaponinfo(WEP_FIRST + mod(floor(a*2.4), WEP_LAST)).netname);
+                       icon = get_weaponinfo(WEP_FIRST + mod(floor(a*2.4), WEP_LAST)).model2;
                        a = bound(0, (when - a) / 4, 1);
                        goto hud_config_notifyprint;
                }
@@ -1726,7 +1686,7 @@ void HUD_Notify(void)
                        {
                                break;
                        }
-                       
+
                        attacker = notify_attackers[j];
                        victim = notify_victims[j];
                        icon = notify_icon[j];
@@ -1865,10 +1825,10 @@ void HUD_Radar(void)
                panel_size_y = bound(0.2, panel_size_y, 1) * vid_conheight;
                panel_pos_x = (vid_conwidth - panel_size_x) / 2;
                panel_pos_y = (vid_conheight - panel_size_y) / 2;
-               
+
                panel_bg = strcat(hud_skin_path, "/border_default"); // always use the default border when maximized
                if(precache_pic(panel_bg) == "") { panel_bg = "gfx/hud/default/border_default"; } // fallback
-               
+
                switch(hud_panel_radar_maximized_zoommode)
                {
                        default:
@@ -1885,7 +1845,7 @@ void HUD_Radar(void)
                                f = 1;
                                break;
                }
-               
+
                switch(hud_panel_radar_maximized_rotation)
                {
                        case 0:
@@ -1914,7 +1874,7 @@ void HUD_Radar(void)
                                f = 1;
                                break;
                }
-               
+
                switch(hud_panel_radar_rotation)
                {
                        case 0:
@@ -2297,7 +2257,7 @@ void HUD_Score(void)
                        score = tm.(teamscores[ts_primary]);
                        if(autocvar__hud_configure)
                                score = 123;
-                       
+
                        if (score > max_fragcount)
                                max_fragcount = score;
 
@@ -2752,7 +2712,7 @@ void HUD_Mod_CTF(vector pos, vector mySize)
        stat_items = getstati(STAT_ITEMS, 0, 24);
        redflag = (stat_items/IT_RED_FLAG_TAKEN) & 3;
        blueflag = (stat_items/IT_BLUE_FLAG_TAKEN) & 3;
-       
+
        if(redflag || blueflag)
                mod_active = 1;
        else
@@ -3029,29 +2989,29 @@ void HUD_Mod_KH(vector pos, vector mySize)
 float kaball_prevstatus; // last remembered status
 float kaball_statuschange_time; // time when the status changed
 
-// we don't need to reset for keepaway since it immediately 
+// we don't need to reset for keepaway since it immediately
 // autocorrects prevstatus as to if the player has the ball or not
 
 void HUD_Mod_Keepaway(vector pos, vector mySize)
 {
        mod_active = 1; // keepaway should always show the mod HUD
-       
+
        float BLINK_FACTOR = 0.15;
        float BLINK_BASE = 0.85;
-       float BLINK_FREQ = 5; 
+       float BLINK_FREQ = 5;
        float kaball_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
-       
+
        float stat_items = getstati(STAT_ITEMS, 0, 24);
        float kaball = (stat_items/IT_KEY1) & 1;
-       
+
        if(kaball != kaball_prevstatus)
        {
                kaball_statuschange_time = time;
                kaball_prevstatus = kaball;
        }
-       
+
        vector kaball_pos, kaball_size;
-       
+
        if(mySize_x > mySize_y) {
                kaball_pos = pos + eX * 0.25 * mySize_x;
                kaball_size = eX * 0.5 * mySize_x + eY * mySize_y;
@@ -3059,13 +3019,13 @@ void HUD_Mod_Keepaway(vector pos, vector mySize)
                kaball_pos = pos + eY * 0.25 * mySize_y;
                kaball_size = eY * 0.5 * mySize_y + eX * mySize_x;
        }
-       
+
        float kaball_statuschange_elapsedtime = time - kaball_statuschange_time;
        float f = bound(0, kaball_statuschange_elapsedtime*2, 1);
-       
+
        if(kaball_prevstatus && f < 1)
                drawpic_aspect_skin_expanding(kaball_pos, "keepawayball_carrying", kaball_size, '1 1 1', panel_fg_alpha * kaball_alpha, DRAWFLAG_NORMAL, f);
-       
+
        if(kaball)
                drawpic_aspect_skin(pos, "keepawayball_carrying", eX * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha * kaball_alpha * f, DRAWFLAG_NORMAL);
 }
@@ -3123,7 +3083,7 @@ void HUD_Mod_Race(vector pos, vector mySize)
        float f; // yet another function has this
        score = me.(scores[ps_primary]);
 
-       if not((scores_flags[ps_primary] & SFL_TIME) && !teamplay) // race/cts record display on HUD
+       if(!(scores_flags[ps_primary] & SFL_TIME) || teamplay) // race/cts record display on HUD
                return; // no records in the actual race
 
        // clientside personal record
@@ -3591,7 +3551,7 @@ void HUD_EngineInfo(void)
                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(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.
@@ -3669,7 +3629,7 @@ void HUD_InfoMessages(void)
 
        vector fontsize;
        fontsize = '0.20 0.20 0' * mySize_y;
-       
+
        float a;
        a = panel_fg_alpha;
 
@@ -3704,9 +3664,7 @@ void HUD_InfoMessages(void)
                        s = sprintf(_("^1Press ^3%s^1 for gamemode info"), getcommandkey("server info", "+show_info"));
                        drawInfoMessage(s)
 
-                       if(gametype == MAPINFO_TYPE_ARENA)
-                               s = _("^1Wait for your turn to join");
-                       else if(gametype == MAPINFO_TYPE_LMS)
+                       if(gametype == MAPINFO_TYPE_LMS)
                        {
                                entity sk;
                                sk = playerslots[player_localnum];
@@ -3795,7 +3753,7 @@ void HUD_InfoMessages(void)
                        }
                }
        }
-       else 
+       else
        {
                s = _("^7Press ^3ESC ^7to show HUD options.");
                drawInfoMessage(s)
@@ -3871,7 +3829,7 @@ void HUD_Physics(void)
                        conversion_factor = 0.0254 * 1.943844492; // 1 m/s = 1.943844492 knots, because 1 knot = 1.852 km/h
                        break;
        }
-       
+
        vector vel = (csqcplayer ? csqcplayer.velocity : pmove_vel);
 
        float max_speed = floor( autocvar_hud_panel_physics_speed_max * conversion_factor + 0.5 );
@@ -3894,9 +3852,9 @@ void HUD_Physics(void)
                        acceleration = (vlen(vel) - vlen(acc_prevspeed));
                else
                        acceleration = (vlen(vel - '0 0 1' * vel_z) - vlen(acc_prevspeed - '0 0 1' * acc_prevspeed_z));
-               
+
                acceleration = acceleration * (1 / max(0.0001, f)) * (0.0254 / 9.80665);
-               
+
                acc_prevspeed = vel;
                acc_prevtime = time;
 
@@ -4097,7 +4055,7 @@ float centerprint_showing;
 
 void centerprint_generic(float new_id, string strMessage, float duration, float countdown_num)
 {
-       //print(sprintf("centerprint_generic(%d, '%s^7', %d, %d);\n", new_id, strMessage, duration, countdown_num));
+       //printf("centerprint_generic(%d, '%s^7', %d, %d);\n", new_id, strMessage, duration, countdown_num);
        float i, j;
 
        if(strMessage == "" && new_id == 0)
@@ -4229,9 +4187,9 @@ void HUD_CenterPrint (void)
                if (scoreboard_bottom >= 0.96 * vid_conheight)
                        return;
                vector target_pos;
-               
+
                target_pos = eY * scoreboard_bottom + eX * 0.5 * (vid_conwidth - panel_size_x);
-               
+
                if(target_pos_y > panel_pos_y)
                {
                        panel_pos = panel_pos + (target_pos - panel_pos) * sqrt(scoreboard_fade_alpha);
@@ -4263,8 +4221,7 @@ void HUD_CenterPrint (void)
        float a, sz, align, current_msg_pos_y = 0, msg_size;
        vector pos;
        string ts;
-
-       n = -1; // if no msg will be displayed, n stays -1
+       float all_messages_expired = TRUE;
 
        pos = panel_pos;
        if (autocvar_hud_panel_centerprint_flip)
@@ -4287,31 +4244,36 @@ void HUD_CenterPrint (void)
                                continue;
                }
 
+               all_messages_expired = FALSE;
 
-               // fade the centerprint_hud in/out 
-               if(centerprint_time[j] < 0)
-                       a = bound(0, (time - centerprint_expire_time[j]) / max(0.0001, autocvar_hud_panel_centerprint_fade_in), 1);
-               else if(centerprint_expire_time[j] - autocvar_hud_panel_centerprint_fade_out > time)
-                       a = bound(0, (time - (centerprint_expire_time[j] - centerprint_time[j])) / max(0.0001, autocvar_hud_panel_centerprint_fade_in), 1);
-               else if(centerprint_expire_time[j] > time)
+               // fade the centerprint_hud in/out
+               if(centerprint_time[j] < 0)  // Expired but forced. Expire time is the fade-in time.
+                       a = (time - centerprint_expire_time[j]) / max(0.0001, autocvar_hud_panel_centerprint_fade_in);
+               else if(centerprint_expire_time[j] - autocvar_hud_panel_centerprint_fade_out > time)  // Regularily printed. Not fading out yet.
+                       a = (time - (centerprint_expire_time[j] - centerprint_time[j])) / max(0.0001, autocvar_hud_panel_centerprint_fade_in);
+               else // Expiring soon, so fade it out.
                        a = (centerprint_expire_time[j] - time) / max(0.0001, autocvar_hud_panel_centerprint_fade_out);
-               else
-                       a = 0;
-               
+
+               if (a <= 0.5/255.0)  // Guaranteed invisible - don't show.
+                       continue;
+               if (a > 1)
+                       a = 1;
+
                // set the size from fading in/out before subsequent fading
-               sz = autocvar_hud_panel_centerprint_fade_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_minfontsize); 
-               
+               sz = autocvar_hud_panel_centerprint_fade_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_minfontsize);
+
                // also fade it based on positioning
                if(autocvar_hud_panel_centerprint_fade_subsequent)
                {
                        a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passone_minalpha, (1 - (g / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passone))), 1); // pass one: all messages after the first have half theAlpha
                        a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passtwo_minalpha, (1 - (g / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passtwo))), 1); // pass two: after that, gradually lower theAlpha even more for each message
                }
-               
+               a *= panel_fg_alpha;
+
                // finally set the size based on the new theAlpha from subsequent fading
-               sz = sz * (autocvar_hud_panel_centerprint_fade_subsequent_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_subsequent_minfontsize)); 
+               sz = sz * (autocvar_hud_panel_centerprint_fade_subsequent_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_subsequent_minfontsize));
                drawfontscale = sz * '1 1 0';
-               
+
                if (centerprint_countdown_num[j])
                        n = tokenizebyseparator(strreplace("^COUNT", count_seconds(centerprint_countdown_num[j]), centerprint_messages[j]), "\n");
                else
@@ -4346,7 +4308,8 @@ void HUD_CenterPrint (void)
                                {
                                        if (align)
                                                pos_x = panel_pos_x + (panel_size_x - stringwidth(ts, TRUE, fontsize)) * align;
-                                       drawcolorcodedstring(pos + eY * 0.5 * (1 - sz) * fontsize_y, ts, fontsize, a * panel_fg_alpha, DRAWFLAG_NORMAL);
+                                       if (a > 0.5/255.0)  // Otherwise guaranteed invisible - don't show. This is checked a second time after some multiplications with other factors were done so temporary changes of these cannot cause flicker.
+                                               drawcolorcodedstring(pos + eY * 0.5 * (1 - sz) * fontsize_y, ts, fontsize, a, DRAWFLAG_NORMAL);
                                        pos_y += fontsize_y;
                                }
                                else
@@ -4354,15 +4317,15 @@ void HUD_CenterPrint (void)
                        }
                }
 
-               ++g; // move next position number up 
-               
+               ++g; // move next position number up
+
                msg_size = pos_y - msg_size;
                if (autocvar_hud_panel_centerprint_flip)
                {
                        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 += (msg_size + CENTERPRINT_SPACING * fontsize_y) * (1 - sqrt(sz));
-                               
+
                        if (pos_y < panel_pos_y) // check if the next message can be shown
                        {
                                drawfontscale = '1 1 0';
@@ -4374,7 +4337,7 @@ void HUD_CenterPrint (void)
                        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 -= (msg_size + CENTERPRINT_SPACING * fontsize_y) * (1 - sqrt(sz));
-                               
+
                        if(pos_y > panel_pos_y + panel_size_y - fontsize_y) // check if the next message can be shown
                        {
                                drawfontscale = '1 1 0';
@@ -4383,7 +4346,7 @@ void HUD_CenterPrint (void)
                }
        }
        drawfontscale = '1 1 0';
-       if (n == -1)
+       if (all_messages_expired)
        {
                centerprint_showing = FALSE;
                reset_centerprint_messages();