]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into Mario/ctf_updates
authorMario <zacjardine@y7mail.com>
Sat, 14 Feb 2015 01:48:50 +0000 (12:48 +1100)
committerMario <zacjardine@y7mail.com>
Sat, 14 Feb 2015 01:48:50 +0000 (12:48 +1100)
1  2 
qcsrc/client/hud.qc

diff --combined qcsrc/client/hud.qc
index d22459af7677df2327d8266a05b5c8f51f7aed57,024a0761e4b51ed5ae5fecb8ae6b80f5b818f829..ce51af46636003ad3a5a288a83686b13ede07a0a
@@@ -5,7 -5,6 +5,7 @@@
  #include "../common/mapinfo.qh"
  #include "../common/nades.qh"
  #include "../server/t_items.qh"
 +#include "../server/mutators/gamemode_ctf.qh"
  
  /*
  ==================
@@@ -141,6 -140,12 +141,12 @@@ vector HUD_Get_Num_Color (float x, floa
        return color;
  }
  
+ float HUD_GetRowCount(float item_count, vector size, float item_aspect)
+ {
+       float aspect = size_y / size_x;
+       return bound(1, floor((sqrt(4 * item_aspect * aspect * item_count + aspect * aspect) + aspect + 0.5) / 2), item_count);
+ }
  float stringwidth_colors(string s, vector theSize)
  {
        return stringwidth(s, true, theSize);
@@@ -425,16 -430,13 +431,13 @@@ void HUD_Weapons(void
        float screen_ar;
        vector center = '0 0 0';
        float weapon_count, weapon_id;
-       float row, column, rows = 0, columns = 0;
+       float row, column, rows = 0, columns;
        float aspect = autocvar_hud_panel_weapons_aspect;
  
-       float panel_weapon_accuracy;
        float timeout = autocvar_hud_panel_weapons_timeout;
        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_full;
        vector barsize = '0 0 0', baroffset = '0 0 0';
        vector ammo_color = '1 0 1';
        float ammo_alpha = 1;
        if(!autocvar_hud_panel_weapons_complainbubble || autocvar__hud_configure || time - complain_weapon_time >= when + fadetime)
                complain_weapon = 0;
  
+       if(autocvar__hud_configure)
+       {
+               if(!weapons_stat)
+                       for(i = WEP_FIRST; i <= WEP_LAST; i += floor((WEP_LAST-WEP_FIRST)/5))
+                               weapons_stat |= WepSet_FromWeapon(i);
+       }
        // determine which weapons are going to be shown
        if (autocvar_hud_panel_weapons_onlyowned)
        {
                if(autocvar__hud_configure)
                {
-                       if (!weapons_stat)
-                               for(i = WEP_FIRST; i <= WEP_LAST; i += floor((WEP_LAST-WEP_FIRST)/5))
-                                       weapons_stat |= WepSet_FromWeapon(i);
                        if(menu_enabled != 2)
                                HUD_Panel_DrawBg(1); // also draw the bg of the entire panel
                }
                // do we own this weapon?
                weapon_count = 0;
                for(i = 0; i <= WEP_LAST-WEP_FIRST; ++i)
-                       if(weapons_stat & WepSet_FromWeapon(weaponorder[i].weapon))
+                       if((weapons_stat & WepSet_FromWeapon(weaponorder[i].weapon)) || (weaponorder[i].weapon == complain_weapon))
                                ++weapon_count;
  
-               // add it anyway if weaponcomplain is shown
-               if(complain_weapon)
-                       ++weapon_count;
                // might as well commit suicide now, no reason to live ;)
                if (weapon_count == 0)
                {
                        return;
                }
  
-               vector max_panel_size = panel_size - '2 2 0' * panel_bg_padding;
+               vector old_panel_size = panel_size;
+               if(panel_bg_padding)
+                       old_panel_size -= '2 2 0' * panel_bg_padding;
  
-               // calculate distribution and size of table cells
-               if(max_panel_size.x > max_panel_size.y)
-               {
-                       while(weapon_count > columns * rows)
-                       {
-                               ++rows;
-                               columns = ceil(max_panel_size.x / (max_panel_size.y / rows * aspect));
-                       }
+               // NOTE: the goal is to use the all-weapons layout and remove unneeded cells
+               // this way weapon icons always have the same size regardless of owned weapon count
  
-                       weapon_size.x = max_panel_size.x / columns;
-                       weapon_size.y = max_panel_size.y / rows;
-                       columns = ceil(weapon_count / rows);
-               }
-               else
-               {
-                       while(weapon_count > columns * rows)
-                       {
-                               ++columns;
-                               rows = ceil(max_panel_size.y / (max_panel_size.x / columns / aspect));
-                       }
+               // get the all-weapons layout
+               rows = HUD_GetRowCount(WEP_COUNT, old_panel_size, aspect);
+               columns = ceil(WEP_COUNT/rows);
+               weapon_size.x = old_panel_size.x / columns;
+               weapon_size.y = old_panel_size.y / rows;
  
-                       weapon_size.x = max_panel_size.x / columns;
-                       weapon_size.y = max_panel_size.y / rows;
-                       rows = ceil(weapon_count / columns);
-               }
+               // reduce rows and columns as needed
+               columns = ceil(weapon_count / rows);
+               rows = ceil(weapon_count / columns);
+               // NOTE: although weapons should aways look the same even if onlyowned is disabled,
+               // we enlarge them a bit when possible to better match the desired aspect ratio
+               // as they look much better
+               weapon_size.x = min(old_panel_size.x / columns, aspect * weapon_size.y);
+               weapon_size.y = min(old_panel_size.y / rows, weapon_size.x / aspect);
  
                // reduce size of the panel
                panel_size.x = columns * weapon_size.x;
                panel_size.y = rows * weapon_size.y;
-               panel_pos.x += (max_panel_size.x - panel_size.x) / 2;
-               panel_pos.y += (max_panel_size.y - panel_size.y) / 2;
-               panel_size += '2 2 0' * panel_bg_padding;
+               panel_pos.x += (old_panel_size.x - panel_size.x) / 2;
+               panel_pos.y += (old_panel_size.y - panel_size.y) / 2;
+               if(panel_bg_padding)
+                       panel_size += '2 2 0' * panel_bg_padding;
        }
        else
                weapon_count = WEP_COUNT;
  
        if(!rows) // if rows is > 0 onlyowned code has already updated these vars
        {
-               rows = panel_size.y/panel_size.x;
-               rows = bound(1, floor((sqrt(4 * aspect * rows * weapon_count + rows * rows) + rows + 0.5) / 2), weapon_count);
+               rows = HUD_GetRowCount(weapon_count, panel_size, aspect);
                columns = ceil(weapon_count/rows);
                weapon_size = eX * panel_size.x*(1/columns) + eY * panel_size.y*(1/rows);
        }
                // draw the weapon accuracy
                if(autocvar_hud_panel_weapons_accuracy)
                {
-                       panel_weapon_accuracy = weapon_accuracy[self.weapon-WEP_FIRST];
+                       float panel_weapon_accuracy = weapon_accuracy[self.weapon-WEP_FIRST];
                        if(panel_weapon_accuracy >= 0)
                        {
                                color = Accuracy_GetColor(panel_weapon_accuracy);
                        // draw ammo status bar
                        if(autocvar_hud_panel_weapons_ammo && (self.ammo_field != ammo_none))
                        {
+                               float ammo_full;
                                a = getstati(GetAmmoStat(self.ammo_field)); // how much ammo do we have?
  
                                if(a > 0)
@@@ -1016,15 -1012,10 +1013,10 @@@ void HUD_Ammo(void
        else
                nade_prevstatus = nade_prevframe = nade_statuschange_time = 0;
  
-       rows = mySize.y/mySize.x;
-       rows = bound(1, floor((sqrt(4 * (3/1) * rows * (total_ammo_count) + rows * rows) + rows + 0.5) / 2), (total_ammo_count));
-       //                               ^^^ ammo item aspect goes here
+       rows = HUD_GetRowCount(total_ammo_count, mySize, 3);
        columns = ceil((total_ammo_count)/rows);
        ammo_size = eX * mySize.x*(1/columns) + eY * mySize.y*(1/rows);
  
        vector offset = '0 0 0'; // fteqcc sucks
        float newSize;
        if(ammo_size.x/ammo_size.y > 3)
@@@ -2310,12 -2301,8 +2302,8 @@@ void HUD_Score(void
                }
                if(spectatee_status == -1)
                {
-                       rows = mySize.y/mySize.x;
-                       rows = bound(1, floor((sqrt(4 * (3/1) * rows * team_count + rows * rows) + rows + 0.5) / 2), team_count);
-                       //                               ^^^ ammo item aspect goes here
+                       rows = HUD_GetRowCount(team_count, mySize, 3);
                        columns = ceil(team_count/rows);
                        score_size = eX * mySize.x*(1/columns) + eY * mySize.y*(1/rows);
  
                        float newSize;
@@@ -2743,9 -2730,8 +2731,8 @@@ void HUD_Mod_CA(vector myPos, vector my
        else //if(gametype == MAPINFO_TYPE_FREEZETAG)
                layout = autocvar_hud_panel_modicons_freezetag_layout;
        float rows, columns, aspect_ratio;
-       rows = mySize.y/mySize.x;
        aspect_ratio = (layout) ? 2 : 1;
-       rows = bound(1, floor((sqrt((4 * aspect_ratio * team_count + rows) * rows) + rows + 0.5) / 2), team_count);
+       rows = HUD_GetRowCount(team_count, mySize, aspect_ratio);
        columns = ceil(team_count/rows);
  
        int i;
  }
  
  // CTF HUD modicon section
 -float redflag_prevframe, blueflag_prevframe; // status during previous frame
 -float redflag_prevstatus, blueflag_prevstatus; // last remembered status
 -float redflag_statuschange_time, blueflag_statuschange_time; // time when the status changed
 +int redflag_prevframe, blueflag_prevframe, yellowflag_prevframe, pinkflag_prevframe, neutralflag_prevframe; // status during previous frame
 +int redflag_prevstatus, blueflag_prevstatus, yellowflag_prevstatus, pinkflag_prevstatus, neutralflag_prevstatus; // last remembered status
 +int redflag_statuschange_time, blueflag_statuschange_time, yellowflag_statuschange_time, pinkflag_statuschange_time, neutralflag_statuschange_time; // time when the status changed
  
  void HUD_Mod_CTF_Reset(void)
  {
 -      redflag_prevstatus = blueflag_prevstatus = redflag_prevframe = blueflag_prevframe = redflag_statuschange_time = blueflag_statuschange_time = 0;
 +      redflag_prevstatus = blueflag_prevstatus = yellowflag_prevstatus = pinkflag_prevstatus = neutralflag_prevstatus = 0;
 +      redflag_prevframe = blueflag_prevframe = yellowflag_prevframe = pinkflag_prevframe = neutralflag_prevframe = 0;
 +      redflag_statuschange_time = blueflag_statuschange_time = yellowflag_statuschange_time = pinkflag_statuschange_time = neutralflag_statuschange_time = 0;
  }
  
  void HUD_Mod_CTF(vector pos, vector mySize)
  {
 -      vector redflag_pos, blueflag_pos;
 +      vector redflag_pos, blueflag_pos, yellowflag_pos, pinkflag_pos, neutralflag_pos;
        vector flag_size;
        float f; // every function should have that
  
 -      float redflag, blueflag; // current status
 -      float redflag_statuschange_elapsedtime, blueflag_statuschange_elapsedtime; // time since the status changed
 -      float stat_items;
 -
 -      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)
 +      int redflag, blueflag, yellowflag, pinkflag, neutralflag; // current status
 +      float redflag_statuschange_elapsedtime, blueflag_statuschange_elapsedtime, yellowflag_statuschange_elapsedtime, pinkflag_statuschange_elapsedtime, neutralflag_statuschange_elapsedtime; // time since the status changed
 +      bool ctf_oneflag; // one-flag CTF mode enabled/disabled
 +      int stat_items = getstati(STAT_CTF_FLAGSTATUS, 0, 24);
 +      float fs, fs2, fs3, size1, size2;
 +      vector e1, e2;
 +
 +      redflag = (stat_items/CTF_RED_FLAG_TAKEN) & 3;
 +      blueflag = (stat_items/CTF_BLUE_FLAG_TAKEN) & 3;
 +      yellowflag = (stat_items/CTF_YELLOW_FLAG_TAKEN) & 3;
 +      pinkflag = (stat_items/CTF_PINK_FLAG_TAKEN) & 3;
 +      neutralflag = (stat_items/CTF_NEUTRAL_FLAG_TAKEN) & 3;
 +      
 +      ctf_oneflag = (stat_items & CTF_FLAG_NEUTRAL);
 +
 +      if(redflag || blueflag || yellowflag || pinkflag || neutralflag)
                mod_active = 1;
        else
                mod_active = 0;
        {
                redflag = 1;
                blueflag = 2;
 +              if(team_count >= 3)
 +                      yellowflag = 2;
 +              if(team_count >= 4)
 +                      pinkflag = 3;
 +              ctf_oneflag = neutralflag = 0; // disable neutral flag in hud editor?
        }
  
        // when status CHANGES, set old status into prevstatus and current status into status
                blueflag_prevframe = blueflag;
        }
  
 +      if (yellowflag != yellowflag_prevframe)
 +      {
 +              yellowflag_statuschange_time = time;
 +              yellowflag_prevstatus = yellowflag_prevframe;
 +              yellowflag_prevframe = yellowflag;
 +      }
 +
 +      if (pinkflag != pinkflag_prevframe)
 +      {
 +              pinkflag_statuschange_time = time;
 +              pinkflag_prevstatus = pinkflag_prevframe;
 +              pinkflag_prevframe = pinkflag;
 +      }
 +
 +      if (neutralflag != neutralflag_prevframe)
 +      {
 +              neutralflag_statuschange_time = time;
 +              neutralflag_prevstatus = neutralflag_prevframe;
 +              neutralflag_prevframe = neutralflag;
 +      }
 +
        redflag_statuschange_elapsedtime = time - redflag_statuschange_time;
        blueflag_statuschange_elapsedtime = time - blueflag_statuschange_time;
 +      yellowflag_statuschange_elapsedtime = time - yellowflag_statuschange_time;
 +      pinkflag_statuschange_elapsedtime = time - pinkflag_statuschange_time;
 +      neutralflag_statuschange_elapsedtime = time - neutralflag_statuschange_time;
  
 -      float BLINK_FACTOR = 0.15;
 -      float BLINK_BASE = 0.85;
 +      const float BLINK_FACTOR = 0.15;
 +      const float BLINK_BASE = 0.85;
        // note:
        //   RMS = sqrt(BLINK_BASE^2 + 0.5 * BLINK_FACTOR^2)
        // thus
        //   BLINK_BASE = sqrt(RMS^2 - 0.5 * BLINK_FACTOR^2)
        // ensure RMS == 1
 -      float BLINK_FREQ = 5; // circle frequency, = 2*pi*frequency in hertz
 +      const float BLINK_FREQ = 5; // circle frequency, = 2*pi*frequency in hertz
  
        string red_icon, red_icon_prevstatus;
 -      float red_alpha, red_alpha_prevstatus;
 +      int red_alpha, red_alpha_prevstatus;
        red_alpha = red_alpha_prevstatus = 1;
 -      switch(redflag) {
 +      switch(redflag)
 +      {
                case 1: red_icon = "flag_red_taken"; break;
                case 2: red_icon = "flag_red_lost"; break;
                case 3: red_icon = "flag_red_carrying"; red_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
                default:
 -                      if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_2))
 +                      if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_1))
                                red_icon = "flag_red_shielded";
                        else
                                red_icon = string_null;
                        break;
        }
 -      switch(redflag_prevstatus) {
 +      switch(redflag_prevstatus)
 +      {
                case 1: red_icon_prevstatus = "flag_red_taken"; break;
                case 2: red_icon_prevstatus = "flag_red_lost"; break;
                case 3: red_icon_prevstatus = "flag_red_carrying"; red_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
                default:
                        if(redflag == 3)
                                red_icon_prevstatus = "flag_red_carrying"; // make it more visible
 -                      else if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_2))
 +                      else if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_1))
                                red_icon_prevstatus = "flag_red_shielded";
                        else
                                red_icon_prevstatus = string_null;
        }
  
        string blue_icon, blue_icon_prevstatus;
 -      float blue_alpha, blue_alpha_prevstatus;
 +      int blue_alpha, blue_alpha_prevstatus;
        blue_alpha = blue_alpha_prevstatus = 1;
 -      switch(blueflag) {
 +      switch(blueflag)
 +      {
                case 1: blue_icon = "flag_blue_taken"; break;
                case 2: blue_icon = "flag_blue_lost"; break;
                case 3: blue_icon = "flag_blue_carrying"; blue_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
                default:
 -                      if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_1))
 +                      if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_2))
                                blue_icon = "flag_blue_shielded";
                        else
                                blue_icon = string_null;
                        break;
        }
 -      switch(blueflag_prevstatus) {
 +      switch(blueflag_prevstatus)
 +      {
                case 1: blue_icon_prevstatus = "flag_blue_taken"; break;
                case 2: blue_icon_prevstatus = "flag_blue_lost"; break;
                case 3: blue_icon_prevstatus = "flag_blue_carrying"; blue_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
                default:
                        if(blueflag == 3)
                                blue_icon_prevstatus = "flag_blue_carrying"; // make it more visible
 -                      else if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_1))
 +                      else if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_2))
                                blue_icon_prevstatus = "flag_blue_shielded";
                        else
                                blue_icon_prevstatus = string_null;
                        break;
        }
  
 -      if(mySize.x > mySize.y) {
 -              if (myteam == NUM_TEAM_1) { // always draw own flag on left
 +      string yellow_icon, yellow_icon_prevstatus;
 +      int yellow_alpha, yellow_alpha_prevstatus;
 +      yellow_alpha = yellow_alpha_prevstatus = 1;
 +      switch(yellowflag)
 +      {
 +              case 1: yellow_icon = "flag_yellow_taken"; break;
 +              case 2: yellow_icon = "flag_yellow_lost"; break;
 +              case 3: yellow_icon = "flag_yellow_carrying"; yellow_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
 +              default:
 +                      if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_3))
 +                              yellow_icon = "flag_yellow_shielded";
 +                      else
 +                              yellow_icon = string_null;
 +                      break;
 +      }
 +      switch(yellowflag_prevstatus)
 +      {
 +              case 1: yellow_icon_prevstatus = "flag_yellow_taken"; break;
 +              case 2: yellow_icon_prevstatus = "flag_yellow_lost"; break;
 +              case 3: yellow_icon_prevstatus = "flag_yellow_carrying"; yellow_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
 +              default:
 +                      if(yellowflag == 3)
 +                              yellow_icon_prevstatus = "flag_yellow_carrying"; // make it more visible
 +                      else if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_3))
 +                              yellow_icon_prevstatus = "flag_yellow_shielded";
 +                      else
 +                              yellow_icon_prevstatus = string_null;
 +                      break;
 +      }
 +
 +      string pink_icon, pink_icon_prevstatus;
 +      int pink_alpha, pink_alpha_prevstatus;
 +      pink_alpha = pink_alpha_prevstatus = 1;
 +      switch(pinkflag)
 +      {
 +              case 1: pink_icon = "flag_pink_taken"; break;
 +              case 2: pink_icon = "flag_pink_lost"; break;
 +              case 3: pink_icon = "flag_pink_carrying"; pink_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
 +              default:
 +                      if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_4))
 +                              pink_icon = "flag_pink_shielded";
 +                      else
 +                              pink_icon = string_null;
 +                      break;
 +      }
 +      switch(pinkflag_prevstatus)
 +      {
 +              case 1: pink_icon_prevstatus = "flag_pink_taken"; break;
 +              case 2: pink_icon_prevstatus = "flag_pink_lost"; break;
 +              case 3: pink_icon_prevstatus = "flag_pink_carrying"; pink_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
 +              default:
 +                      if(pinkflag == 3)
 +                              pink_icon_prevstatus = "flag_pink_carrying"; // make it more visible
 +                      else if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_4))
 +                              pink_icon_prevstatus = "flag_pink_shielded";
 +                      else
 +                              pink_icon_prevstatus = string_null;
 +                      break;
 +      }
 +
 +      string neutral_icon, neutral_icon_prevstatus;
 +      int neutral_alpha, neutral_alpha_prevstatus;
 +      neutral_alpha = neutral_alpha_prevstatus = 1;
 +      switch(neutralflag)
 +      {
 +              case 1: neutral_icon = "flag_neutral_taken"; break;
 +              case 2: neutral_icon = "flag_neutral_lost"; break;
 +              case 3: neutral_icon = "flag_neutral_carrying"; neutral_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
 +              default:
 +                      if((stat_items & CTF_SHIELDED))
 +                              neutral_icon = "flag_neutral_shielded";
 +                      else
 +                              neutral_icon = string_null;
 +                      break;
 +      }
 +      switch(neutralflag_prevstatus)
 +      {
 +              case 1: neutral_icon_prevstatus = "flag_neutral_taken"; break;
 +              case 2: neutral_icon_prevstatus = "flag_neutral_lost"; break;
 +              case 3: neutral_icon_prevstatus = "flag_neutral_carrying"; neutral_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
 +              default:
 +                      if(neutralflag == 3)
 +                              neutral_icon_prevstatus = "flag_neutral_carrying"; // make it more visible
 +                      else if((stat_items & CTF_SHIELDED))
 +                              neutral_icon_prevstatus = "flag_neutral_shielded";
 +                      else
 +                              neutral_icon_prevstatus = string_null;
 +                      break;
 +      }
 +
 +      if(ctf_oneflag)
 +      {
 +              // hacky, but these aren't needed
 +              red_icon = red_icon_prevstatus = blue_icon = blue_icon_prevstatus = yellow_icon = yellow_icon_prevstatus = pink_icon = pink_icon_prevstatus = string_null;
 +              fs = fs2 = fs3 = 1;
 +      }
 +      else switch(team_count)
 +      {
 +              default:
 +              case 2: fs = 0.5; fs2 = 0.5; fs3 = 0.5; break;
 +              case 3: fs = 1; fs2 = 0.35; fs3 = 0.35; break;
 +              case 4: fs = 0.75; fs2 = 0.25; fs3 = 0.5; break;
 +      }
 +
 +      if(mySize_x > mySize_y)
 +      {
 +              size1 = mySize_x;
 +              size2 = mySize_y;
 +              e1 = eX;
 +              e2 = eY;
 +      }
 +      else
 +      {
 +              size1 = mySize_y;
 +              size2 = mySize_x;
 +              e1 = eY;
 +              e2 = eX;
 +      }
 +
 +      switch(myteam)
 +      {
 +              default:
 +              case NUM_TEAM_1:
 +              {
                        redflag_pos = pos;
 -                      blueflag_pos = pos + eX * 0.5 * mySize.x;
 -              } else {
 -                      blueflag_pos = pos;
 -                      redflag_pos = pos + eX * 0.5 * mySize.x;
 +                      blueflag_pos = pos + eX * fs2 * size1;
 +                      yellowflag_pos = pos - eX * fs2 * size1;
 +                      pinkflag_pos = pos + eX * fs3 * size1;
 +                      break;
                }
 -              flag_size = eX * 0.5 * mySize.x + eY * mySize.y;
 -      } else {
 -              if (myteam == NUM_TEAM_1) { // always draw own flag on left
 -                      redflag_pos = pos;
 -                      blueflag_pos = pos + eY * 0.5 * mySize.y;
 -              } else {
 +              case NUM_TEAM_2:
 +              {
 +                      redflag_pos = pos + eX * fs2 * size1;
                        blueflag_pos = pos;
 -                      redflag_pos = pos + eY * 0.5 * mySize.y;
 +                      yellowflag_pos = pos - eX * fs2 * size1;
 +                      pinkflag_pos = pos + eX * fs3 * size1;
 +                      break;
 +              }
 +              case NUM_TEAM_3:
 +              {
 +                      redflag_pos = pos + eX * fs3 * size1;
 +                      blueflag_pos = pos - eX * fs2 * size1;
 +                      yellowflag_pos = pos;
 +                      pinkflag_pos = pos + eX * fs2 * size1;
 +                      break;
 +              }
 +              case NUM_TEAM_4:
 +              {
 +                      redflag_pos = pos - eX * fs2 * size1;
 +                      blueflag_pos = pos + eX * fs3 * size1;
 +                      yellowflag_pos = pos + eX * fs2 * size1;
 +                      pinkflag_pos = pos;
 +                      break;
                }
 -              flag_size = eY * 0.5 * mySize.y + eX * mySize.x;
        }
 +      neutralflag_pos = pos;
 +      flag_size = e1 * fs * size1 + e2 * size2;
  
        f = bound(0, redflag_statuschange_elapsedtime*2, 1);
        if(red_icon_prevstatus && f < 1)
                drawpic_aspect_skin_expanding(blueflag_pos, blue_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * blue_alpha_prevstatus, DRAWFLAG_NORMAL, f);
        if(blue_icon)
                drawpic_aspect_skin(blueflag_pos, blue_icon, flag_size, '1 1 1', panel_fg_alpha * blue_alpha * f, DRAWFLAG_NORMAL);
 +
 +      f = bound(0, yellowflag_statuschange_elapsedtime*2, 1);
 +      if(yellow_icon_prevstatus && f < 1)
 +              drawpic_aspect_skin_expanding(yellowflag_pos, yellow_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * yellow_alpha_prevstatus, DRAWFLAG_NORMAL, f);
 +      if(yellow_icon)
 +              drawpic_aspect_skin(yellowflag_pos, yellow_icon, flag_size, '1 1 1', panel_fg_alpha * yellow_alpha * f, DRAWFLAG_NORMAL);
 +
 +      f = bound(0, pinkflag_statuschange_elapsedtime*2, 1);
 +      if(pink_icon_prevstatus && f < 1)
 +              drawpic_aspect_skin_expanding(pinkflag_pos, pink_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * pink_alpha_prevstatus, DRAWFLAG_NORMAL, f);
 +      if(pink_icon)
 +              drawpic_aspect_skin(pinkflag_pos, pink_icon, flag_size, '1 1 1', panel_fg_alpha * pink_alpha * f, DRAWFLAG_NORMAL);
 +
 +      f = bound(0, neutralflag_statuschange_elapsedtime*2, 1);
 +      if(neutral_icon_prevstatus && f < 1)
 +              drawpic_aspect_skin_expanding(neutralflag_pos, neutral_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * neutral_alpha_prevstatus, DRAWFLAG_NORMAL, f);
 +      if(neutral_icon)
 +              drawpic_aspect_skin(neutralflag_pos, neutral_icon, flag_size, '1 1 1', panel_fg_alpha * neutral_alpha * f, DRAWFLAG_NORMAL);
  }
  
  // Keyhunt HUD modicon section
@@@ -3537,9 -3325,8 +3524,8 @@@ void HUD_Mod_Dom(vector myPos, vector m
  
        int layout = autocvar_hud_panel_modicons_dom_layout;
        float rows, columns, aspect_ratio;
-       rows = mySize.y/mySize.x;
        aspect_ratio = (layout) ? 3 : 1;
-       rows = bound(1, floor((sqrt((4 * aspect_ratio * team_count + rows) * rows) + rows + 0.5) / 2), team_count);
+       rows = HUD_GetRowCount(team_count, mySize, aspect_ratio);
        columns = ceil(team_count/rows);
  
        int i;