Merge branch 'master' into terencehill/centerprint_stuff
authorterencehill <piuntn@gmail.com>
Sat, 16 Jul 2011 20:37:21 +0000 (22:37 +0200)
committerterencehill <piuntn@gmail.com>
Sat, 16 Jul 2011 20:37:21 +0000 (22:37 +0200)
41 files changed:
_hud_descriptions.cfg
defaultXonotic.cfg
hud_luminos.cfg
hud_luminos_minimal.cfg
hud_luminos_old.cfg
hud_luminos_xhair_minimal.cfg
hud_nexuiz.cfg
qcsrc/client/Main.qc
qcsrc/client/View.qc
qcsrc/client/autocvars.qh
qcsrc/client/hud.qc
qcsrc/client/hud.qh
qcsrc/client/hud_config.qc
qcsrc/client/main.qh
qcsrc/client/miscfunctions.qc
qcsrc/client/scoreboard.qc
qcsrc/client/vehicles/vehicles.qc
qcsrc/common/constants.qh
qcsrc/common/util.qh
qcsrc/menu/classes.c
qcsrc/menu/xonotic/dialog_hudpanel_centerprint.c [new file with mode: 0644]
qcsrc/menu/xonotic/mainwindow.c
qcsrc/server/arena.qc
qcsrc/server/builtins.qh
qcsrc/server/campaign.qc
qcsrc/server/cl_client.qc
qcsrc/server/clientcommands.qc
qcsrc/server/ctf.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc
qcsrc/server/gamecommand.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/gamemode_keepaway.qc
qcsrc/server/mutators/gamemode_keyhunt.qc
qcsrc/server/mutators/gamemode_keyhunt.qh
qcsrc/server/mutators/mutator_nix.qc
qcsrc/server/t_items.qc
qcsrc/server/teamplay.qc
qcsrc/server/vote.qc
qcsrc/server/w_minstanex.qc

index e4c669663324bca895414a5e8e954451199aaa02..b4a4cd478b4f62584f412ebdcb5cb79411b40ff1 100644 (file)
@@ -31,8 +31,6 @@ seta hud_configure_grid "" "snap to grid when moving/resizing panels"
 seta hud_configure_grid_xsize "" "snap to X * vid_conwidth"
 seta hud_configure_grid_ysize "" "snap to Y * vid_conheight"
 
-seta scr_centerpos "" "Y position of the centerprint"
-
 seta hud_panel_weapons "" "enable/disable this panel"
 seta hud_panel_weapons_pos "" "position of this panel"
 seta hud_panel_weapons_size "" "size of this panel"
@@ -234,3 +232,18 @@ seta hud_panel_physics_flip "" "flip speed/acceleration positions"
 seta hud_panel_physics_progressbar "" "enable progressbar in panel (2 = only for speed; 3 = only for acceleration)"
 seta hud_panel_physics_acceleration_progressbar_mode "" "0 = progressbar increases from the center to the right if the acceleration is positive, to the left if it's negative; 1 = progressbar increases from the border in the same direction for both positive and negative accelerations"
 seta hud_panel_physics_text "" "show text in panel (2 = only for speed; 3 = only for acceleration)"
+
+seta hud_panel_centerprint "" "enable/disable this panel"
+seta hud_panel_centerprint_pos "" "position of this base of the panel"
+seta hud_panel_centerprint_size "" "size of this panel"
+seta hud_panel_centerprint_bg "" "if set to something else than \"\" = override default background"
+seta hud_panel_centerprint_bg_color "" "if set to something else than \"\" = override default panel background color"
+seta hud_panel_centerprint_bg_color_team "" "override panel color with team color in team based games"
+seta hud_panel_centerprint_bg_alpha "" "if set to something else than \"\" = override default panel background alpha"
+seta hud_panel_centerprint_bg_border "" "if set to something else than \"\" = override default size of border around the background"
+seta hud_panel_centerprint_bg_padding "" "if set to something else than \"\" = override default padding of contents from border"
+seta hud_panel_centerprint_align "" "text alignment: 0 left, 0.5 center, 1 right"
+seta hud_panel_centerprint_flip "" "invert messages order"
+seta hud_panel_centerprint_fontscale "" "scale the text font by this amount"
+seta hud_panel_centerprint_time "" "message duration (NOTE: certain messages have a fixed duration)"
+seta hud_panel_centerprint_fadetime "" "how long a message takes to fade out (this time is included in the message duration and can't be > 1)"
index 27ab53efc715dd34111bd703be3353ca0b36fe46..0db263b247f268c8a4f7ec943917548d0a08b223 100644 (file)
@@ -1684,7 +1684,6 @@ set capturelimit 0
 
 // hud: font size
 seta hud_fontsize 11
-seta scr_centersize 12
 seta hud_width 560
 
 // these entities are not referenced by anything directly, they just represent
index 4c11d42079856dee560dc26463a74c9e2001df10..5ddc5daa0c378f83000f58b421d6da2f5ce679ec 100644 (file)
@@ -23,14 +23,12 @@ seta hud_progressbar_speed_color "1 0.75 0"
 seta hud_progressbar_acceleration_color "0.5 0.75 1"
 seta hud_progressbar_acceleration_neg_color "0.125 0.25 0.5"
 
-seta _hud_panelorder "15 12 9 10 5 6 14 0 7 4 11 2 1 3 8 13 "
+seta _hud_panelorder "15 12 9 10 5 6 14 0 7 4 11 2 1 3 8 13 16 "
 
 seta hud_configure_grid "1"
 seta hud_configure_grid_xsize "0.010000"
 seta hud_configure_grid_ysize "0.010000"
 
-seta scr_centerpos "0.25"
-
 seta hud_panel_weapons 1
 seta hud_panel_weapons_pos "0.940000 0.180000"
 seta hud_panel_weapons_size "0.060000 0.610000"
@@ -233,4 +231,19 @@ seta hud_panel_physics_acceleration_progressbar_mode "0"
 seta hud_panel_physics_progressbar "1"
 seta hud_panel_physics_text "1"
 
+seta hud_panel_centerprint 1
+seta hud_panel_centerprint_pos "0.180000 0.260000"
+seta hud_panel_centerprint_size "0.650000 0.210000"
+seta hud_panel_centerprint_bg "0"
+seta hud_panel_centerprint_bg_color ""
+seta hud_panel_centerprint_bg_color_team ""
+seta hud_panel_centerprint_bg_alpha ""
+seta hud_panel_centerprint_bg_border ""
+seta hud_panel_centerprint_bg_padding ""
+seta hud_panel_centerprint_align "0.5"
+seta hud_panel_centerprint_flip "1"
+seta hud_panel_centerprint_fontscale "1"
+seta hud_panel_centerprint_time "3"
+seta hud_panel_centerprint_fadetime "0.25"
+
 menu_sync
index 5d803304475b0b1a78ee8416ef6a2c62bff8db55..1c7c7e32d6b78f786ea0cc57cb8cc19405d64e63 100644 (file)
@@ -23,14 +23,12 @@ seta hud_progressbar_speed_color "1 0.75 0"
 seta hud_progressbar_acceleration_color "0.5 0.75 1"
 seta hud_progressbar_acceleration_neg_color "0.125 0.25 0.5"
 
-seta _hud_panelorder "10 3 0 14 6 9 13 4 1 2 11 12 7 5 8 15 "
+seta _hud_panelorder "10 3 0 14 6 9 13 4 1 2 11 12 7 5 8 15 16 "
 
 seta hud_configure_grid "1"
 seta hud_configure_grid_xsize "0.010000"
 seta hud_configure_grid_ysize "0.010000"
 
-seta scr_centerpos "0.25"
-
 seta hud_panel_weapons 1
 seta hud_panel_weapons_pos "0.350000 0.940000"
 seta hud_panel_weapons_size "0.300000 0.060000"
@@ -233,4 +231,19 @@ seta hud_panel_physics_acceleration_progressbar_mode "0"
 seta hud_panel_physics_progressbar "3"
 seta hud_panel_physics_text "2"
 
+seta hud_panel_centerprint 1
+seta hud_panel_centerprint_pos "0.180000 0.260000"
+seta hud_panel_centerprint_size "0.650000 0.210000"
+seta hud_panel_centerprint_bg "0"
+seta hud_panel_centerprint_bg_color ""
+seta hud_panel_centerprint_bg_color_team ""
+seta hud_panel_centerprint_bg_alpha ""
+seta hud_panel_centerprint_bg_border ""
+seta hud_panel_centerprint_bg_padding ""
+seta hud_panel_centerprint_align "0.5"
+seta hud_panel_centerprint_flip "1"
+seta hud_panel_centerprint_fontscale "1"
+seta hud_panel_centerprint_time "3"
+seta hud_panel_centerprint_fadetime "0.25"
+
 menu_sync
index a5e16e75a4acb7430e89a8c3e67bf1e07980ce77..8d49e094bb013767426cf4c9af82b438b5d3d3cf 100644 (file)
@@ -23,14 +23,12 @@ seta hud_progressbar_speed_color "1 0.75 0"
 seta hud_progressbar_acceleration_color "0.5 0.75 1"
 seta hud_progressbar_acceleration_neg_color "0.125 0.25 0.5"
 
-seta _hud_panelorder "15 10 9 6 8 14 5 0 4 13 2 7 1 3 11 12 "
+seta _hud_panelorder "15 10 9 6 8 14 5 0 4 13 2 7 1 3 11 12 16 "
 
 seta hud_configure_grid "1"
 seta hud_configure_grid_xsize "0.010000"
 seta hud_configure_grid_ysize "0.010000"
 
-seta scr_centerpos "0.25"
-
 seta hud_panel_weapons 1
 seta hud_panel_weapons_pos "0.920000 0.090000"
 seta hud_panel_weapons_size "0.060000 0.630000"
@@ -233,4 +231,19 @@ seta hud_panel_physics_acceleration_progressbar_mode "0"
 seta hud_panel_physics_progressbar "1"
 seta hud_panel_physics_text "1"
 
+seta hud_panel_centerprint 1
+seta hud_panel_centerprint_pos "0.180000 0.260000"
+seta hud_panel_centerprint_size "0.650000 0.210000"
+seta hud_panel_centerprint_bg "0"
+seta hud_panel_centerprint_bg_color ""
+seta hud_panel_centerprint_bg_color_team ""
+seta hud_panel_centerprint_bg_alpha ""
+seta hud_panel_centerprint_bg_border ""
+seta hud_panel_centerprint_bg_padding ""
+seta hud_panel_centerprint_align "0.5"
+seta hud_panel_centerprint_flip "1"
+seta hud_panel_centerprint_fontscale "1"
+seta hud_panel_centerprint_time "3"
+seta hud_panel_centerprint_fadetime "0.25"
+
 menu_sync
index 55a1149e9226adbe2140ddaae253cf51cdd4fcba..3f4cacf0703e8ce514f9d74fa3b73d64a387b0e7 100644 (file)
@@ -23,14 +23,12 @@ seta hud_progressbar_speed_color "1 0.75 0"
 seta hud_progressbar_acceleration_color "0.5 0.75 1"
 seta hud_progressbar_acceleration_neg_color "0.125 0.25 0.5"
 
-seta _hud_panelorder "15 3 1 2 11 10 0 14 6 9 13 4 12 7 5 8 "
+seta _hud_panelorder "15 3 1 2 11 10 0 14 6 9 13 4 12 7 5 8 16 "
 
 seta hud_configure_grid "1"
 seta hud_configure_grid_xsize "0.010000"
 seta hud_configure_grid_ysize "0.010000"
 
-seta scr_centerpos "0.25"
-
 seta hud_panel_weapons 1
 seta hud_panel_weapons_pos "0.350000 0.940000"
 seta hud_panel_weapons_size "0.300000 0.060000"
@@ -233,4 +231,19 @@ seta hud_panel_physics_acceleration_progressbar_mode "0"
 seta hud_panel_physics_progressbar "3"
 seta hud_panel_physics_text "2"
 
+seta hud_panel_centerprint 1
+seta hud_panel_centerprint_pos "0.180000 0.260000"
+seta hud_panel_centerprint_size "0.650000 0.210000"
+seta hud_panel_centerprint_bg "0"
+seta hud_panel_centerprint_bg_color ""
+seta hud_panel_centerprint_bg_color_team ""
+seta hud_panel_centerprint_bg_alpha ""
+seta hud_panel_centerprint_bg_border ""
+seta hud_panel_centerprint_bg_padding ""
+seta hud_panel_centerprint_align "0.5"
+seta hud_panel_centerprint_flip "1"
+seta hud_panel_centerprint_fontscale "1"
+seta hud_panel_centerprint_time "3"
+seta hud_panel_centerprint_fadetime "0.25"
+
 menu_sync
index 87bebc5d035fd5e49d33a74a149e23ffcce4bbc3..2c9ade5b69240767ea0efebee4ef86dadb4b09a3 100644 (file)
@@ -23,14 +23,12 @@ seta hud_progressbar_speed_color "0.25 0.25 1"
 seta hud_progressbar_acceleration_color "0.25 1 0.25"
 seta hud_progressbar_acceleration_neg_color "1 0.25 0.25"
 
-seta _hud_panelorder "15 0 11 8 5 6 14 9 13 7 2 3 1 10 12 4 "
+seta _hud_panelorder "15 0 11 8 5 6 14 9 13 7 2 3 1 10 12 4 16 "
 
 seta hud_configure_grid "1"
 seta hud_configure_grid_xsize "0.01"
 seta hud_configure_grid_ysize "0.01"
 
-seta scr_centerpos "0.25"
-
 seta hud_panel_weapons 1
 seta hud_panel_weapons_pos "0.370000 0.870000"
 seta hud_panel_weapons_size "0.340000 0.060000"
@@ -233,4 +231,19 @@ seta hud_panel_physics_acceleration_progressbar_mode "0"
 seta hud_panel_physics_progressbar "3"
 seta hud_panel_physics_text "2"
 
+seta hud_panel_centerprint 1
+seta hud_panel_centerprint_pos "0.180000 0.260000"
+seta hud_panel_centerprint_size "0.650000 0.210000"
+seta hud_panel_centerprint_bg "0"
+seta hud_panel_centerprint_bg_color ""
+seta hud_panel_centerprint_bg_color_team ""
+seta hud_panel_centerprint_bg_alpha ""
+seta hud_panel_centerprint_bg_border ""
+seta hud_panel_centerprint_bg_padding ""
+seta hud_panel_centerprint_align "0.5"
+seta hud_panel_centerprint_flip "1"
+seta hud_panel_centerprint_fontscale "1"
+seta hud_panel_centerprint_time "3"
+seta hud_panel_centerprint_fadetime "0.25"
+
 menu_sync
index 95a01ab0e767501ac9b257ff2b266536dbe893cf..6d90e1080363324f89edd644f2f4d20ad1c1ebee 100644 (file)
@@ -1328,6 +1328,17 @@ void Net_Notify() {
        {
                HUD_Centerprint(ReadString(), ReadString(), ReadShort(), ReadByte());
        }
+       else if(type == CSQC_CENTERPRINT_GENERIC)
+       {
+               float id;
+               string s;
+               id = ReadByte();
+               s = ReadString();
+               if (id != 0 && s != "")
+                       centerprint_generic(id, s, ReadByte(), ReadByte());
+               else
+                       centerprint_generic(id, s, 0, 0);
+       }
 }
 
 void Net_WeaponComplain() {
index 48566db5739ae1d9b43e401a16613d71aa6edc7d..476991137586a62dec20cce20dbb33173857100e 100644 (file)
@@ -1419,24 +1419,12 @@ void CSQC_common_hud(void)
     HUD_DrawScoreboard();
 
     if (scoreboard_active) // scoreboard/accuracy
-    {
         HUD_Reset();
-        // HUD_DrawScoreboard takes care of centerprint_start
-    }
     else if (intermission == 2) // map voting screen
     {
         HUD_FinaleOverlay();
         HUD_Reset();
-
-        centerprint_start_x = 0;
-        centerprint_start_y = autocvar_scr_centerpos * vid_conheight;
-    }
-    else // hud
-    {
-        centerprint_start_x = 0;
-        centerprint_start_y = autocvar_scr_centerpos * vid_conheight;
     }
-
        /*
        switch(hud)
        {
@@ -1453,9 +1441,6 @@ void CSQC_common_hud(void)
             break;
        }
        */
-       
-    HUD_DrawCenterPrint();
-    
 }
 
 
index 8e60d8212fef8f1c6bd8996694c4f54518057320..b1c2cda1b5f9d00eb543b1fa27aa78f108138fc4 100644 (file)
@@ -219,6 +219,12 @@ float autocvar_hud_panel_healtharmor_progressbar_gfx_damage;
 float autocvar_hud_panel_healtharmor_progressbar_gfx_lowhealth;
 float autocvar_hud_panel_healtharmor_progressbar_gfx_smooth;
 
+float autocvar_hud_panel_centerprint;
+float autocvar_hud_panel_centerprint_align;
+float autocvar_hud_panel_centerprint_fadetime;
+float autocvar_hud_panel_centerprint_flip;
+float autocvar_hud_panel_centerprint_fontscale;
+float autocvar_hud_panel_centerprint_time;
 float autocvar_hud_panel_healtharmor_text;
 float autocvar_hud_panel_infomessages;
 float autocvar_hud_panel_infomessages_flip;
@@ -333,9 +339,6 @@ var float autocvar_scoreboard_highlight_alpha = 0.10;
 var float autocvar_scoreboard_highlight_alpha_self = 0.25;
 float autocvar_scoreboard_offset_left;
 float autocvar_scoreboard_offset_right;
-float autocvar_scr_centerpos;
-float autocvar_scr_centersize;
-float autocvar_scr_centertime;
 float autocvar_v_flipped;
 float autocvar_vid_conheight;
 float autocvar_vid_conwidth;
index 6b11719567d055e4234fd81ddb8344f3ba4316e8..25a26121b83c09a49db2003436b40245ca638565 100644 (file)
@@ -142,183 +142,6 @@ float stringwidth_nocolors(string s, vector theSize)
        return stringwidth(s, FALSE, theSize);
 }
 
-#define CENTERPRINT_MAX_LINES 30
-string centerprint_messages[CENTERPRINT_MAX_LINES];
-float centerprint_width[CENTERPRINT_MAX_LINES];
-float centerprint_time;
-float centerprint_expire;
-float centerprint_num;
-float centerprint_offset_hint;
-vector centerprint_fontsize;
-
-void centerprint(string strMessage)
-{
-       float i, j, n, hcount;
-       string s;
-
-       centerprint_fontsize = HUD_GetFontsize("scr_centersize");
-
-       centerprint_expire = min(centerprint_expire, time); // if any of the returns happens, this message will fade out
-
-       if(autocvar_scr_centertime <= 0)
-               return;
-
-       if(strMessage == "")
-               return;
-
-       // strip trailing newlines
-       j = strlen(strMessage) - 1;
-       while(substring(strMessage, j, 1) == "\n" && j >= 0)
-               j = j - 1;
-       strMessage = substring(strMessage, 0, j + 1);
-
-       if(strMessage == "")
-               return;
-
-       // strip leading newlines and remember them, they are a hint that the message should be lower on the screen
-       j = 0;
-       while(substring(strMessage, j, 1) == "\n" && j < strlen(strMessage))
-               j = j + 1;
-       strMessage = substring(strMessage, j, strlen(strMessage) - j);
-       centerprint_offset_hint = j;
-
-       if(strMessage == "")
-               return;
-
-       // if we get here, we have a message. Initialize its height.
-       centerprint_num = 0;
-
-       n = tokenizebyseparator(strMessage, "\n");
-       i = hcount = 0;
-       for(j = 0; j < n; ++j)
-       {
-               getWrappedLine_remaining = argv(j);
-               while(getWrappedLine_remaining)
-               {
-                       s = getWrappedLine(vid_conwidth * 0.75, centerprint_fontsize, stringwidth_colors);
-                       if(centerprint_messages[i] != s) // don't fade the same message in, looks stupid
-                               centerprint_time = time;
-                       if(centerprint_messages[i])
-                               strunzone(centerprint_messages[i]);
-                       centerprint_messages[i] = strzone(s);
-                       centerprint_width[i] = stringwidth(s, TRUE, centerprint_fontsize);
-                       ++i;
-
-                       // half height for empty lines looks better
-                       if(s == "")
-                               hcount += 0.5;
-                       else
-                               hcount += 1;
-
-                       if(i >= CENTERPRINT_MAX_LINES)
-                               break;
-               }
-       }
-
-       float h, havail;
-       h = centerprint_fontsize_y*hcount;
-
-       havail = vid_conheight;
-       if(autocvar_con_chatpos < 0)
-               havail -= (-autocvar_con_chatpos + autocvar_con_chat) * autocvar_con_chatsize; // avoid overlapping chat
-       if(havail > vid_conheight - 70)
-               havail = vid_conheight - 70; // avoid overlapping HUD
-
-#if 0
-       float forbiddenmin, forbiddenmax, allowedmin, allowedmax, preferred;
-
-       // here, the centerprint would cover the crosshair. REALLY BAD.
-       forbiddenmin = vid_conheight * 0.5 - h - 16;
-       forbiddenmax = vid_conheight * 0.5 + 16;
-
-       allowedmin = scoreboard_bottom;
-       allowedmax = havail - h;
-       preferred = (havail - h)/2;
-
-
-       // possible orderings (total: 4! / 4 = 6)
-       //  allowedmin allowedmax forbiddenmin forbiddenmax
-       //  forbiddenmin forbiddenmax allowedmin allowedmax
-       if(allowedmax < forbiddenmin || allowedmin > forbiddenmax)
-       {
-               // forbidden doesn't matter in this case
-               centerprint_start_y = bound(allowedmin, preferred, allowedmax);
-       }
-       //  allowedmin forbiddenmin allowedmax forbiddenmax
-       else if(allowedmin < forbiddenmin && allowedmax < forbiddenmax)
-       {
-               centerprint_start_y = bound(allowedmin, preferred, forbiddenmin);
-       }
-       //  allowedmin forbiddenmin forbiddenmax allowedmax
-       else if(allowedmin < forbiddenmin)
-       {
-               // make sure the forbidden zone is not covered
-               if(preferred > (forbiddenmin + forbiddenmax) * 0.5)
-                       centerprint_start_y = bound(allowedmin, preferred, forbiddenmin);
-               else
-                       centerprint_start_y = bound(forbiddenmax, preferred, allowedmin);
-       }
-       //  forbiddenmin allowedmin allowedmax forbiddenmax
-       else if(allowedmax < forbiddenmax)
-       {
-               // it's better to leave the allowed zone (overlap with scoreboard) than
-               // to cover the forbidden zone (crosshair)
-               if(preferred > (forbiddenmin + forbiddenmax) * 0.5)
-                       centerprint_start_y = forbiddenmax;
-               else
-                       centerprint_start_y = forbiddenmin;
-       }
-       //  forbiddenmin allowedmin forbiddenmax allowedmax
-       else
-       {
-               centerprint_start_y = bound(forbiddenmax, preferred, allowedmax);
-       }
-#else
-#endif
-
-       centerprint_num = i;
-
-       centerprint_expire = time + autocvar_scr_centertime;
-}
-
-void HUD_DrawCenterPrint (void)
-{
-       float i;
-       vector pos;
-       string ts;
-       float a, sz;
-
-       if(time - centerprint_time < 0.25)
-               a = (time - centerprint_time) / 0.25;
-       else
-               a = bound(0, 1 - 4 * (time - centerprint_expire), 1);
-
-       if(a <= 0)
-               return;
-
-       sz = 0.8 + (a / 5);
-
-       if(centerprint_num * autocvar_scr_centersize > 24 && scoreboard_active) // 24 = height of Scoreboard text
-               centerprint_start_y = scoreboard_bottom + centerprint_fontsize_y;
-
-       pos = centerprint_start;
-       for (i=0; i<centerprint_num; i = i + 1)
-       {
-               ts = centerprint_messages[i];
-               drawfontscale = sz * '1 1 0';
-               pos_x = (vid_conwidth - stringwidth(ts, TRUE, centerprint_fontsize)) * 0.5;
-               if (ts != "")
-               {
-                       drawcolorcodedstring(pos + '0 1 0' * (1 - sz) * 0.5 *centerprint_fontsize_y, ts, centerprint_fontsize, a, DRAWFLAG_NORMAL);
-                       pos_y = pos_y + centerprint_fontsize_y;
-               }
-               else
-                       // half height for empty lines looks better
-                       pos_y = pos_y + sz * centerprint_fontsize_y * 0.5;
-               drawfontscale = '1 1 0';
-       }
-}
-
 void drawstringright(vector position, string text, vector scale, vector rgb, float alpha, float flag)
 {
        position_x -= 2 / 3 * strlen(text) * scale_x;
@@ -643,6 +466,7 @@ void HUD_Weapons(void)
        }
 
        HUD_Panel_UpdateCvars(weapons);
+       HUD_Panel_ApplyFadeAlpha();
 
        if (timeout && time >= weapontime + timeout && !autocvar__hud_configure)
        {
@@ -1029,6 +853,7 @@ void HUD_Ammo(void)
                hud_configure_active_panel = HUD_PANEL_AMMO;
 
        HUD_Panel_UpdateCvars(ammo);
+       HUD_Panel_ApplyFadeAlpha();
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -1214,6 +1039,7 @@ void HUD_Powerups(void)
        }
 
        HUD_Panel_UpdateCvars(powerups);
+       HUD_Panel_ApplyFadeAlpha();
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -1368,6 +1194,7 @@ void HUD_HealthArmor(void)
        }
 
        HUD_Panel_UpdateCvars(healtharmor);
+       HUD_Panel_ApplyFadeAlpha();
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -2006,92 +1833,90 @@ void HUD_KillNotify(string s1, string s2, string s3, float type, float msg) // s
        }
 }
 
-#define DAMAGE_CENTERPRINT_SPACER NEWLINES
-
 void HUD_Centerprint(string s1, string s2, float type, float msg)
 {
        float gentle;
        gentle = (autocvar_cl_gentle || autocvar_cl_gentle_messages);
        if(msg == MSG_SUICIDE) {
                if (type == DEATH_TEAMCHANGE) {
-                       centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, sprintf(_("You are now on: %s"), s1)));
+                       centerprint(sprintf(_("You are now on: %s"), s1));
                } else if (type == DEATH_AUTOTEAMCHANGE) {
-                       centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, sprintf(_("You have been moved into a different team to improve team balance\nYou are now on: %s"), s1)));
+                       centerprint(sprintf(_("You have been moved into a different team to improve team balance\nYou are now on: %s"), s1));
                } else if (type == DEATH_CAMP) {
                        if(gentle)
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1Reconsider your tactics, camper!")));
+                               centerprint(_("^1Reconsider your tactics, camper!"));
                        else
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1Die camper!")));
+                               centerprint(_("^1Die camper!"));
                } else if (type == DEATH_NOAMMO) {
                        if(gentle)
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1You are reinserted into the game for running out of ammo...")));
+                               centerprint(_("^1You are reinserted into the game for running out of ammo..."));
                        else
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1You were killed for running out of ammo...")));
+                               centerprint(_("^1You were killed for running out of ammo..."));
                } else if (type == DEATH_ROT) {
                        if(gentle)
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1You need to preserve your health")));
+                               centerprint(_("^1You need to preserve your health"));
                        else
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1You grew too old without taking your medicine")));
+                               centerprint(_("^1You grew too old without taking your medicine"));
                } else if (type == KILL_TEAM_RED || type == KILL_TEAM_BLUE) {
                        if(gentle)
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1Don't go against team mates!")));
+                               centerprint(_("^1Don't go against team mates!"));
                        else
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1Don't shoot your team mates!")));
+                               centerprint(_("^1Don't shoot your team mates!"));
                } else if (type == DEATH_QUIET) {
                        // do nothing
                } else { // generic message
                        if(gentle)
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1You need to be more careful!")));
+                               centerprint(_("^1You need to be more careful!"));
                        else
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1You killed your own dumb self!")));
+                               centerprint(_("^1You killed your own dumb self!"));
                }
        } else if(msg == MSG_KILL) {
                if (type == KILL_TEAM_RED || type == KILL_TEAM_BLUE) {
                        if(gentle) {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, sprintf(_("^1Moron! You went against ^7%s^1, a team mate!"), s1)));
+                               centerprint(sprintf(_("^1Moron! You went against ^7%s^1, a team mate!"), s1));
                        } else {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, sprintf(_("^1Moron! You fragged ^7%s^1, a team mate!"), s1)));
+                               centerprint(sprintf(_("^1Moron! You fragged ^7%s^1, a team mate!"), s1));
                        }
                } else if (type == KILL_FIRST_BLOOD) {
                        if(gentle) {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1First score")));
+                               centerprint(_("^1First score"));
                        } else {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1First blood")));
+                               centerprint(_("^1First blood"));
                        }
                } else if (type == KILL_FIRST_VICTIM) {
                        if(gentle) {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1First casualty")));
+                               centerprint(_("^1First casualty"));
                        } else {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1First victim")));
+                               centerprint(_("^1First victim"));
                        }
                } else if (type == KILL_TYPEFRAG) { // s2 contains "advanced kill messages" such as ping, handicap...
                        if(gentle) {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, sprintf(_("^1You scored against ^7%s^1 who was typing!"), s1), s2));
+                               centerprint(strcat(sprintf(_("^1You scored against ^7%s^1 who was typing!"), s1), s2));
                        } else {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, sprintf(_("^1You typefragged ^7%s"), s1), s2));
+                               centerprint(strcat(sprintf(_("^1You typefragged ^7%s"), s1), s2));
                        }
                } else if (type == KILL_TYPEFRAGGED) {
                        if(gentle) {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, sprintf(_("^1You were scored against by ^7%s^1 while you were typing!"), s1), s2));
+                               centerprint(strcat(sprintf(_("^1You were scored against by ^7%s^1 while you were typing!"), s1), s2));
                        } else {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, sprintf(_("^1You were typefragged by ^7%s"), s1), s2));
+                               centerprint(strcat(sprintf(_("^1You were typefragged by ^7%s"), s1), s2));
                        }
                } else if (type == KILL_FRAG) {
                        if(gentle) {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, sprintf(_("^4You scored against ^7%s"), s1), s2));
+                               centerprint(strcat(sprintf(_("^4You scored against ^7%s"), s1), s2));
                        } else {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, sprintf(_("^4You fragged ^7%s"), s1), s2));
+                               centerprint(strcat(sprintf(_("^4You fragged ^7%s"), s1), s2));
                        }
                } else { // generic message
                        if(gentle) {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, sprintf(_("^1You were scored against by ^7%s"), s1), s2));
+                               centerprint(strcat(sprintf(_("^1You were scored against by ^7%s"), s1), s2));
                        } else {
-                               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, sprintf(_("^1You were fragged by ^7%s"), s1), s2));
+                               centerprint(strcat(sprintf(_("^1You were fragged by ^7%s"), s1), s2));
                        }
                }
        } else if(msg == MSG_KILL_ACTION) {
                // TODO: invent more centerprints here?
-               centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, _("^1Watch your step!")));
+               centerprint(_("^1Watch your step!"));
        }
 }
 
@@ -2105,6 +1930,7 @@ void HUD_Notify (void)
                hud_configure_active_panel = HUD_PANEL_NOTIFY;
 
        HUD_Panel_UpdateCvars(notify);
+       HUD_Panel_ApplyFadeAlpha();
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -2418,6 +2244,7 @@ void HUD_Timer(void)
                hud_configure_active_panel = HUD_PANEL_TIMER;
 
        HUD_Panel_UpdateCvars(timer);
+       HUD_Panel_ApplyFadeAlpha();
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -2475,6 +2302,7 @@ void HUD_Radar(void)
                hud_configure_active_panel = HUD_PANEL_RADAR;
 
        HUD_Panel_UpdateCvars(radar);
+       HUD_Panel_ApplyFadeAlpha();
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -2726,6 +2554,7 @@ void HUD_Score(void)
                hud_configure_active_panel = HUD_PANEL_SCORE;
 
        HUD_Panel_UpdateCvars(score);
+       HUD_Panel_ApplyFadeAlpha();
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -2910,6 +2739,7 @@ void HUD_RaceTimer (void)
                hud_configure_active_panel = HUD_PANEL_RACETIMER;
 
        HUD_Panel_UpdateCvars(racetimer);
+       HUD_Panel_ApplyFadeAlpha();
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -3105,6 +2935,7 @@ void HUD_VoteWindow(void)
                return;
 
        HUD_Panel_UpdateCvars(vote);
+       HUD_Panel_ApplyFadeAlpha();
 
        if(uid2name_dialog)
        {
@@ -3860,6 +3691,7 @@ void HUD_ModIcons(void)
                hud_configure_active_panel = HUD_PANEL_MODICONS;
 
        HUD_Panel_UpdateCvars(modicons);
+       HUD_Panel_ApplyFadeAlpha();
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -3914,6 +3746,7 @@ void HUD_DrawPressedKeys(void)
 
 
        HUD_Panel_UpdateCvars(pressedkeys);
+       HUD_Panel_ApplyFadeAlpha();
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -3978,6 +3811,7 @@ void HUD_Chat(void)
                hud_configure_active_panel = HUD_PANEL_CHAT;
 
        HUD_Panel_UpdateCvars(chat);
+       HUD_Panel_ApplyFadeAlpha();
 
        if(autocvar__con_chat_maximized && !autocvar__hud_configure) // draw at full screen height if maximized
        {
@@ -4053,6 +3887,7 @@ void HUD_EngineInfo(void)
                hud_configure_active_panel = HUD_PANEL_ENGINEINFO;
 
        HUD_Panel_UpdateCvars(engineinfo);
+       HUD_Panel_ApplyFadeAlpha();
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -4115,6 +3950,7 @@ void HUD_InfoMessages(void)
                hud_configure_active_panel = HUD_PANEL_INFOMESSAGES;
 
        HUD_Panel_UpdateCvars(infomessages);
+       HUD_Panel_ApplyFadeAlpha();
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -4300,6 +4136,7 @@ void HUD_Physics(void)
                hud_configure_active_panel = HUD_PANEL_PHYSICS;
 
        HUD_Panel_UpdateCvars(physics);
+       HUD_Panel_ApplyFadeAlpha();
 
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
@@ -4510,6 +4347,290 @@ void HUD_Physics(void)
                drawstring_aspect(panel_pos + acceleration_offset, strcat(ftos_decimals(acceleration, 2), "g"), panel_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 }
 
+// CenterPrint (#16)
+//
+#define CENTERPRINT_MAX_MSGS 10
+#define CENTERPRINT_MAX_ENTRIES 50
+#define CENTERPRINT_SPACING 0.7
+float cpm_index;
+string centerprint_messages[CENTERPRINT_MAX_MSGS];
+float centerprint_msgID[CENTERPRINT_MAX_MSGS];
+float centerprint_time[CENTERPRINT_MAX_MSGS];
+float centerprint_expire_time[CENTERPRINT_MAX_MSGS];
+float centerprint_countdown_num[CENTERPRINT_MAX_MSGS];
+float centerprint_fadetime;
+float centerprint_showing;
+
+void centerprint_generic(float new_id, string strMessage, float duration, float countdown_num)
+{
+       float i, j;
+
+       if(strMessage == "" && new_id == 0)
+               return;
+
+       // strip trailing newlines
+       j = strlen(strMessage) - 1;
+       while(substring(strMessage, j, 1) == "\n" && j >= 0)
+               --j;
+       if (j < strlen(strMessage) - 1)
+               strMessage = substring(strMessage, 0, j + 1);
+
+       if(strMessage == "" && new_id == 0)
+               return;
+
+       // strip leading newlines
+       j = 0;
+       while(substring(strMessage, j, 1) == "\n" && j < strlen(strMessage))
+               ++j;
+       if (j > 0)
+               strMessage = substring(strMessage, j, strlen(strMessage) - j);
+
+       if(strMessage == "" && new_id == 0)
+               return;
+
+       if (!centerprint_showing)
+               centerprint_showing = TRUE;
+
+       centerprint_fadetime = bound(0, autocvar_hud_panel_centerprint_fadetime, 1);
+
+       for (i=0, j=cpm_index; i<CENTERPRINT_MAX_MSGS; ++i, ++j)
+       {
+               if (j == CENTERPRINT_MAX_MSGS)
+                       j = 0;
+               if (new_id && new_id == centerprint_msgID[j])
+               {
+                       if (strMessage == "" && centerprint_messages[j] != "" && centerprint_countdown_num[j] == 0)
+                       {
+                               // fade out the current msg (duration and countdown_num are ignored)
+                               centerprint_time[j] = centerprint_fadetime;
+                               if (centerprint_expire_time[j] > time + centerprint_fadetime || centerprint_expire_time[j] < time)
+                                       centerprint_expire_time[j] = time + centerprint_fadetime;
+                               return;
+                       }
+                       break; // found a msg with the same id, at position j
+               }
+       }
+
+       if (i == CENTERPRINT_MAX_MSGS)
+       {
+               // a msg with the same id was not found, add the msg at the next position
+               --cpm_index;
+               if (cpm_index == -1)
+                       cpm_index = CENTERPRINT_MAX_MSGS - 1;
+               j = cpm_index;
+       }
+       if(centerprint_messages[j])
+               strunzone(centerprint_messages[j]);
+       centerprint_messages[j] = strzone(strMessage);
+       centerprint_msgID[j] = new_id;
+       if (duration < 0)
+               centerprint_time[j] = -1;
+       else
+       {
+               if(duration == 0)
+                       duration = max(1, autocvar_hud_panel_centerprint_time);
+               centerprint_time[j] = duration;
+               centerprint_expire_time[j] = time + duration;
+       }
+       centerprint_countdown_num[j] = countdown_num;
+}
+
+void centerprint(string strMessage)
+{
+       centerprint_generic(0, strMessage, autocvar_hud_panel_centerprint_time, 0);
+}
+
+void reset_centerprint_messages(void)
+{
+       float i;
+       for (i=0; i<CENTERPRINT_MAX_MSGS; ++i)
+       {
+               centerprint_expire_time[i] = 0;
+               centerprint_time[i] = 1;
+               centerprint_msgID[i] = 0;
+               if(centerprint_messages[i])
+                       strunzone(centerprint_messages[i]);
+               centerprint_messages[i] = string_null;
+       }
+}
+float hud_configure_cp_generation_time;
+void HUD_CenterPrint (void)
+{
+       if(!autocvar__hud_configure)
+       {
+               if(!autocvar_hud_panel_centerprint) return;
+
+               if (hud_configure_prev && hud_configure_prev != -1)
+                       reset_centerprint_messages();
+       }
+       else
+       {
+               hud_configure_active_panel = HUD_PANEL_CENTERPRINT;
+
+               if (!hud_configure_prev)
+                       reset_centerprint_messages();
+               if (time > hud_configure_cp_generation_time)
+               {
+                       float r;
+                       r = random();
+                       if (r > 0.9)
+                               centerprint_generic(floor(r*1000), strcat(sprintf("^3Countdown message at time %s", seconds_tostring(time)), ", seconds left: %d"), 1, 10);
+                       else if (r > 0.8)
+                               centerprint_generic(0, sprintf("^1Multiline message at time %s that\n^1lasts longer than normal", seconds_tostring(time)), 20, 0);
+                       else
+                               centerprint(sprintf("Message at time %s", seconds_tostring(time)));
+                       hud_configure_cp_generation_time = time + 1 + random()*4;
+               }
+       }
+
+       HUD_Panel_UpdateCvars(centerprint);
+
+       // this panel doesn't fade when showing the scoreboard
+       if(autocvar__menu_alpha)
+               HUD_Panel_ApplyFadeAlpha();
+
+       if(scoreboard_fade_alpha)
+       {
+               // move the panel below the scoreboard
+               if (scoreboard_bottom >= 0.96 * vid_conheight)
+                       return;
+               vector target_pos;
+               target_pos = eY * scoreboard_bottom + eX * 0.5 * (vid_conwidth - panel_size_x);
+               panel_pos = panel_pos + (target_pos - panel_pos) * sqrt(scoreboard_fade_alpha);
+               panel_size_y = min(panel_size_y, vid_conheight - scoreboard_bottom);
+       }
+
+       HUD_Panel_DrawBg(1);
+
+       if (!centerprint_showing)
+               return;
+
+       if(panel_bg_padding)
+       {
+               panel_pos += '1 1 0' * panel_bg_padding;
+               panel_size -= '2 2 0' * panel_bg_padding;
+       }
+
+       float entries, height;
+       vector fontsize;
+       // entries = bound(1, floor(CENTERPRINT_MAX_ENTRIES * 4 * panel_size_y/panel_size_x), CENTERPRINT_MAX_ENTRIES);
+       // height = panel_size_y/entries;
+       // fontsize = '1 1 0' * height;
+       height = vid_conheight/40 * autocvar_hud_panel_centerprint_fontscale;
+       fontsize = '1 1 0' * height;
+       entries = bound(1, floor(panel_size_y/height), CENTERPRINT_MAX_ENTRIES);
+
+       float i, j, k, n;
+       float a, sz, align, current_msg_pos_y, msg_size;
+       vector pos;
+       string ts;
+
+       n = -1; // if no msg will be displayed, n stays -1
+
+       pos = panel_pos;
+       if (autocvar_hud_panel_centerprint_flip)
+               pos_y += panel_size_y;
+       align = bound(0, autocvar_hud_panel_centerprint_align, 1);
+       for (i=0, j=cpm_index; i<CENTERPRINT_MAX_MSGS; ++i, ++j)
+       {
+               if (j == CENTERPRINT_MAX_MSGS)
+                       j = 0;
+               if (centerprint_expire_time[j] < time)
+               {
+                       if (centerprint_countdown_num[j] && centerprint_time[j] > 0)
+                       {
+                               centerprint_countdown_num[j] = centerprint_countdown_num[j] - 1;
+                               if (centerprint_countdown_num[j] == 0)
+                                       continue;
+                               centerprint_expire_time[j] = centerprint_expire_time[j] + centerprint_time[j];
+                       }
+                       else
+                               continue;
+               }
+               if (centerprint_time[j] < 0 || centerprint_expire_time[j] - centerprint_fadetime > time)
+               {
+                       a = 1;
+                       sz = 1;
+               }
+               else if (centerprint_expire_time[j] > time)
+               {
+                       a = (centerprint_expire_time[j] - time) / centerprint_fadetime;
+                       sz = 0.8 + a * (1 - 0.8);
+               }
+
+               drawfontscale = sz * '1 1 0';
+               if (centerprint_countdown_num[j])
+                       n = tokenizebyseparator(sprintf(centerprint_messages[j], centerprint_countdown_num[j]), "\n");
+               else
+                       n = tokenizebyseparator(centerprint_messages[j], "\n");
+               if (autocvar_hud_panel_centerprint_flip)
+               {
+                       // check if the message can be entirely shown
+                       for(k = 0; k < n; ++k)
+                       {
+                               getWrappedLine_remaining = argv(k);
+                               while(getWrappedLine_remaining)
+                               {
+                                       ts = getWrappedLine(panel_size_x * sz, fontsize, stringwidth_colors);
+                                       if (ts != "")
+                                               pos_y -= fontsize_y;
+                                       else
+                                               pos_y -= fontsize_y * CENTERPRINT_SPACING/2;
+                                       if (pos_y < panel_pos_y) // check if the next line can be shown
+                                       {
+                                               drawfontscale = '1 1 0';
+                                               return;
+                                       }
+                               }
+                       }
+                       current_msg_pos_y = pos_y; // save starting pos (first line) of the current message
+               }
+
+               msg_size = pos_y;
+               for(k = 0; k < n; ++k)
+               {
+                       getWrappedLine_remaining = argv(k);
+                       while(getWrappedLine_remaining)
+                       {
+                               ts = getWrappedLine(panel_size_x * sz, fontsize, stringwidth_colors);
+                               if (ts != "")
+                               {
+                                       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);
+                                       pos_y += fontsize_y;
+                               }
+                               else
+                                       pos_y += fontsize_y * CENTERPRINT_SPACING/2;
+                               if (!autocvar_hud_panel_centerprint_flip && pos_y > panel_pos_y + panel_size_y - fontsize_y) // check if the next line can be shown
+                               {
+                                       drawfontscale = '1 1 0';
+                                       return;
+                               }
+                       }
+               }
+               msg_size = pos_y - msg_size;
+               if (autocvar_hud_panel_centerprint_flip)
+               {
+                       pos_y = 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(a));
+               }
+               else
+               {
+                       pos_y += CENTERPRINT_SPACING * fontsize_y;
+                       if (a < 1 && centerprint_msgID[j] == 0) // messages with id can be replaced just after they are faded out, so never move over them the next messages
+                               pos_y -= (msg_size + CENTERPRINT_SPACING * fontsize_y) * (1 - sqrt(a));
+               }
+       }
+       drawfontscale = '1 1 0';
+       if (n == -1)
+       {
+               centerprint_showing = FALSE;
+               reset_centerprint_messages();
+       }
+}
+
 /*
 ==================
 Main HUD system
@@ -4559,6 +4680,8 @@ switch (id) {\
                 HUD_InfoMessages(); break;\
        case (HUD_PANEL_PHYSICS):\
                 HUD_Physics(); break;\
+       case (HUD_PANEL_CENTERPRINT):\
+                HUD_CenterPrint(); break;\
 } ENDS_WITH_CURLY_BRACE
 
 void HUD_Main (void)
@@ -4589,6 +4712,14 @@ void HUD_Main (void)
        else if(autocvar__menu_alpha == 0 && scoreboard_fade_alpha == 0)
                hud_fade_alpha = 1;
 
+       // panels that we want to be active together with the scoreboard
+       // they must call HUD_Panel_ApplyFadeAlpha(); only when showing the menu
+       if(scoreboard_fade_alpha == 1)
+       {
+               HUD_CenterPrint();
+               return;
+       }
+
        if(!autocvar__hud_configure && !hud_fade_alpha)
                return;
 
@@ -4707,9 +4838,6 @@ void HUD_Main (void)
        if(autocvar__con_chat_maximized)
                HUD_Chat(); // HUD_DrawPanel(HUD_PANEL_CHAT);
 
-       if (autocvar__hud_configure && spectatee_status && hud_configure_prev == -1) // try to join if we are in hud_configure mode, but still spectating, and in the first frame (in order to get rid of motd when launching a server via the menu "HUD Setup" button)
-               localcmd("cmd selectteam auto; cmd join\n");
-
        if(autocvar__hud_configure && tab_panel != -1)
        {
                HUD_Panel_UpdatePosSizeForId(tab_panel)
index fc3dd7422183fddc9aa1dc283bed76ff59529893..ca9296799e8ecb6134645387c1e66fcaf1267859 100644 (file)
@@ -1,7 +1,5 @@
 float log(float f);
 
-vector centerprint_start;
-
 float panel_order[HUD_PANEL_NUM];
 string hud_panelorder_prev;
 
@@ -156,6 +154,14 @@ if(panel_bg_color_team_str == "") {\
        panel_bg_color_team = stof(panel_bg_color_team_str);\
 }
 
+// the check doesn't allow to fade this panel when showing the panel-specific menu dialog
+#define HUD_Panel_ApplyFadeAlpha()\
+if(!(menu_enabled == 2 && highlightedPanel == hud_configure_active_panel))\
+{\
+       panel_bg_alpha *= hud_fade_alpha;\
+       panel_fg_alpha *= hud_fade_alpha;\
+} ENDS_WITH_CURLY_BRACE
+
 // Get value for panel_bg_alpha: if "" fetch default, else use panel_bg_alpha. Also do various menu dialog fadeout/in checks, and minalpha checks
 // comment on line 3 of macro: // do not set a minalpha cap when showing the config dialog for this panel
 #define HUD_Panel_GetBgAlpha()\
@@ -170,19 +176,14 @@ if(autocvar__hud_configure) {\
                panel_bg_alpha = (1 - autocvar__menu_alpha) * max(cvar("hud_configure_bg_minalpha"), panel_bg_alpha) + autocvar__menu_alpha * panel_bg_alpha;\
        else\
                panel_bg_alpha = max(cvar("hud_configure_bg_minalpha"), panel_bg_alpha);\
-} if(!(menu_enabled == 2 && highlightedPanel == hud_configure_active_panel)) {\
-       panel_bg_alpha *= hud_fade_alpha;\
 }
 
 // Get value for panel_fg_alpha. Also do various minalpha checks
 // comment on line 2 of macro: // ALWAYS show disabled panels at 0.25 alpha when in config mode
-// comment on line 4 of macro: // don't fade this panel when showing the panel-specific menu dialog
 #define HUD_Panel_GetFgAlpha()\
 panel_fg_alpha = autocvar_hud_panel_fg_alpha;\
 if(autocvar__hud_configure && !panel_enabled)\
        panel_fg_alpha = 0.25;\
-if(!(menu_enabled == 2 && highlightedPanel == hud_configure_active_panel))\
-       panel_fg_alpha *= hud_fade_alpha;
 
 // Get border. See comments above, it's similar.
 #define HUD_Panel_GetBorder()\
@@ -283,6 +284,7 @@ if(menu_enabled == 2 && hud_configure_active_panel == highlightedPanel) {\
 switch(id) { \
        case HUD_PANEL_INFOMESSAGES: HUD_Panel_UpdateCvars(infomessages) break; \
        case HUD_PANEL_PHYSICS: HUD_Panel_UpdateCvars(physics); break;\
+       case HUD_PANEL_CENTERPRINT: HUD_Panel_UpdateCvars(centerprint); break;\
 }
 
 #define HUD_Panel_UpdateCvarsForId(id) \
@@ -320,6 +322,7 @@ HUD_Panel_GetBorder()
 switch(id) { \
        case HUD_PANEL_INFOMESSAGES: HUD_Panel_UpdatePosSize(infomessages) break;\
        case HUD_PANEL_PHYSICS: HUD_Panel_UpdatePosSize(physics); break;\
+       case HUD_PANEL_CENTERPRINT: HUD_Panel_UpdatePosSize(centerprint); break;\
 }
 
 #define HUD_Panel_UpdatePosSizeForId(id) \
index 0923e4ed97e1603fc14251ce566c70489d20f817..9ff1e0e90a5c1b5ae651c65a25d0d295323d3281 100644 (file)
@@ -45,9 +45,6 @@ void HUD_Panel_ExportCfg(string cfgname)
                HUD_Write_Cvar_q("hud_configure_grid_ysize");
                HUD_Write("\n");
 
-               HUD_Write_Cvar_q("scr_centerpos");
-               HUD_Write("\n");
-
                // common cvars for all panels
                float i;
                for (i = 0; i < HUD_PANEL_NUM; ++i)
@@ -124,6 +121,13 @@ void HUD_Panel_ExportCfg(string cfgname)
                                        HUD_Write_PanelCvar_q("_progressbar");
                                        HUD_Write_PanelCvar_q("_acceleration_mode");
                                        break;
+                               case HUD_PANEL_CENTERPRINT:
+                                       HUD_Write_PanelCvar_q("_align");
+                                       HUD_Write_PanelCvar_q("_flip");
+                                       HUD_Write_PanelCvar_q("_fontscale");
+                                       HUD_Write_PanelCvar_q("_time");
+                                       HUD_Write_PanelCvar_q("_fadetime");
+                                       break;
                        }
                        HUD_Write("\n");
                }
index a0634d42c981244604f5a913051fe74e46af9e3c..64399b20a3e035e6ad899978225cdfadb44a581d 100644 (file)
@@ -144,6 +144,7 @@ float camera_roll;
 vector camera_direction;
 
 void centerprint(string strMessage);
+void centerprint_generic(float new_id, string strMessage, float duration, float countdown_num);
 
 #define ALPHA_MIN_VISIBLE 0.003
 
index 0ba6097701ebe85295efa9179652aa92f42bf0aa..7301fbf0bbf2922fa30b14f83c487e770239da5e 100644 (file)
@@ -20,7 +20,7 @@ void restartAnnouncer_Think() {
        countdown_rounded = floor(0.5 + countdown);
        if(countdown <= 0) {
                if (!spectatee_status) //do cprint only for players
-                       centerprint(_("^1Begin!"));
+                       centerprint_generic(CPID_GAME_STARTING, _("^1Begin!"), 1, 0);
 
                sound(world, CH_INFO, strcat("announcer/", autocvar_cl_announcer, "/begin.wav"), VOL_BASEVOICE, ATTN_NONE);
                //reset maptime announcers now as well
@@ -31,7 +31,7 @@ void restartAnnouncer_Think() {
        }
        else {
                if (!spectatee_status) //do cprint only for players
-                       centerprint(sprintf(_("^1Game starts in %d seconds"), countdown_rounded));
+                       centerprint_generic(CPID_GAME_STARTING, _("^1Game starts in %d seconds"), 1, countdown_rounded);
 
                if(countdown_rounded <= 3 && countdown_rounded >= 1) {
                        sound(world, CH_INFO, strcat("announcer/", autocvar_cl_announcer, "/", ftos(countdown_rounded), ".wav"), VOL_BASEVOICE, ATTN_NONE);
index 67b7f746c8d43f0b2711ff6f655d1ca22d5a88c9..93f851876da157a0a229127cfdf8cac4111272b9 100644 (file)
@@ -1168,9 +1168,6 @@ void HUD_DrawScoreboard()
        vector sb_heading_fontsize;
        sb_heading_fontsize = hud_fontsize * 2;
        drawstring(pos, _("Scoreboard"), sb_heading_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-       
-       centerprint_start_x = vid_conwidth - 0.5 * (pos_x + stringwidth(_("Scoreboard"), FALSE, sb_heading_fontsize));
-       centerprint_start_y = pos_y;
 
        pos_y += sb_heading_fontsize_y + hud_fontsize_y * 0.25;
 
index a06190b3ded7c21dec7800d60693e910e8268107..8041bcb3e1da7653fc9146dfc069c63e74798d27 100644 (file)
@@ -308,9 +308,6 @@ void CSQC_SPIDER_HUD()
     else
         drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL);
 
-
-    HUD_DrawCenterPrint();
-
        if (scoreboard_showscores)
                HUD_DrawScoreboard();
     else
@@ -495,8 +492,6 @@ void CSQC_RAPTOR_HUD()
         }
     }
 
-    HUD_DrawCenterPrint();
-
        if (scoreboard_showscores)
                HUD_DrawScoreboard();
     else
@@ -638,9 +633,6 @@ void CSQC_WAKIZASHI_HUD()
     else
         drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL);
 
-
-    HUD_DrawCenterPrint();
-
        if (scoreboard_showscores)
                HUD_DrawScoreboard();
     else
index e253ee5c71a3b5f32318edc47d17185449ea4f85..de486577bd022513c06ec886552e9287459a72bb 100644 (file)
@@ -83,6 +83,7 @@ const float RANKINGS_CNT = 15;
 
 const float CSQC_KILLNOTIFY = 0;
 const float CSQC_CENTERPRINT = 1;
+const float CSQC_CENTERPRINT_GENERIC = 2;
 
 const float ENT_CLIENT = 0;
 const float ENT_CLIENT_DEAD = 1;
@@ -593,9 +594,6 @@ float HITTYPE_RESERVED = 0x1000; // unused yet
 #define FRAGS_PLAYER_NONSOLID -616
 // we can use this frags value for both
 
-//misc. stuff
-#define NEWLINES "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
-
 // water levels
 float WATERLEVEL_NONE = 0;
 float WATERLEVEL_WETFEET = 1;
@@ -604,6 +602,18 @@ float WATERLEVEL_SUBMERGED = 3;
 
 float MAX_SHOT_DISTANCE = 32768;
 
+//centerprint ID list
+float CPID_TEAMCHANGE = 1;
+float CPID_CTF_CAPTURESHIELD = 2;
+float CPID_MINSTA_FINDAMMO = 3;
+float CPID_NIX_WPNCHANGE = 4;
+float CPID_DISCONNECT_IDLING = 5;
+float CPID_ROUND_STARTING = 6;
+float CPID_GAME_STARTING = 7;
+float CPID_TIMEOUT_COUNTDOWN = 8;
+float CPID_MOTD = 9;
+float CPID_KH_MSG = 10;
+
 // CSQC centerprint/notify message types
 float MSG_SUICIDE = 0;
 float MSG_KILL = 1;
@@ -678,7 +688,8 @@ float HUD_PANEL_CHAT                = 12;
 float HUD_PANEL_ENGINEINFO     = 13;
 float HUD_PANEL_INFOMESSAGES   = 14;
 float HUD_PANEL_PHYSICS        = 15;
-float HUD_PANEL_NUM            = 16; // always last panel id + 1, please increment when adding a new panel
+float HUD_PANEL_CENTERPRINT    = 16;
+float HUD_PANEL_NUM            = 17; // always last panel id + 1, please increment when adding a new panel
 
 string HUD_PANELNAME_WEAPONS           = "weapons";
 string HUD_PANELNAME_AMMO              = "ammo";
@@ -696,6 +707,7 @@ string HUD_PANELNAME_CHAT           = "chat";
 string HUD_PANELNAME_ENGINEINFO                = "engineinfo";
 string HUD_PANELNAME_INFOMESSAGES      = "infomessages";
 string HUD_PANELNAME_PHYSICS   = "physics";
+string HUD_PANELNAME_CENTERPRINT       = "centerprint";
 
 float HUD_MENU_ENABLE          = 0;
 
index 9071c1c7cc1ae5aa4ab29d592e713e6621195be2..2eee6d74ef1a4d369286c1fcc01a71588ccd130d 100644 (file)
@@ -222,6 +222,7 @@ switch(id) {\
        case HUD_PANEL_ENGINEINFO: panel_name = HUD_PANELNAME_ENGINEINFO; break; \
        case HUD_PANEL_INFOMESSAGES: panel_name = HUD_PANELNAME_INFOMESSAGES; break; \
        case HUD_PANEL_PHYSICS: panel_name = HUD_PANELNAME_PHYSICS; break; \
+       case HUD_PANEL_CENTERPRINT: panel_name = HUD_PANELNAME_CENTERPRINT; break; \
 } ENDS_WITH_CURLY_BRACE
 
 // Get name of specified panel id
index 61f5a4877d27bbf506a949372e6520d4239b40cc..5b7331e3752be37be4231150c89627e38c5baa5e 100644 (file)
 #include "xonotic/dialog_hudpanel_infomessages.c"
 #include "xonotic/dialog_hudpanel_weapons.c"
 #include "xonotic/dialog_hudpanel_physics.c"
+#include "xonotic/dialog_hudpanel_centerprint.c"
 #include "xonotic/slider_picmip.c"
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.c b/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.c
new file mode 100644 (file)
index 0000000..9628783
--- /dev/null
@@ -0,0 +1,44 @@
+#ifdef INTERFACE
+CLASS(XonoticHUDCenterprintDialog) EXTENDS(XonoticRootDialog)
+       METHOD(XonoticHUDCenterprintDialog, fill, void(entity))
+       ATTRIB(XonoticHUDCenterprintDialog, title, string, _("Centerprint"))
+       ATTRIB(XonoticHUDCenterprintDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+       ATTRIB(XonoticHUDCenterprintDialog, intendedWidth, float, 0.4)
+       ATTRIB(XonoticHUDCenterprintDialog, rows, float, 15)
+       ATTRIB(XonoticHUDCenterprintDialog, columns, float, 4)
+       ATTRIB(XonoticHUDCenterprintDialog, name, string, "HUDcenterprint")
+ENDCLASS(XonoticHUDCenterprintDialog)
+#endif
+
+#ifdef IMPLEMENTATION
+void XonoticHUDCenterprintDialog_fill(entity me)
+{
+       entity e;
+       string panelname = "centerprint";
+
+       DIALOG_HUDPANEL_COMMON();
+
+       me.TR(me);
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Message duration:")));
+               me.TD(me, 1, 2.6, e = makeXonoticSlider(1, 10, 1, "hud_panel_centerprint_time"));
+       me.TR(me);
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Fade time:")));
+               me.TD(me, 1, 2.6, e = makeXonoticSlider(0, 1, 0.05, "hud_panel_centerprint_fadetime"));
+       me.TR(me);
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_centerprint_flip", _("Flip messages order")));
+       me.TR(me);
+               me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Text alignment:")));
+       me.TR(me);
+               me.TDempty(me, 0.2);
+                       me.TD(me, 1, 3.8/3, e = makeXonoticRadioButton(3, "hud_panel_centerprint_align", "0", _("Left")));
+                       me.TD(me, 1, 3.8/3, e = makeXonoticRadioButton(3, "hud_panel_centerprint_align", "0.5", _("Center")));
+                       me.TD(me, 1, 3.8/3, e = makeXonoticRadioButton(3, "hud_panel_centerprint_align", "1", _("Right")));
+       me.TR(me);
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Font scale:")));
+               me.TD(me, 1, 2.6, e = makeXonoticSlider(0.5, 2, 0.1, "hud_panel_centerprint_fontscale"));
+}
+#endif
index feec5a9b92595baa6cbbdc808ae926a3ea3a2793..55d496047138cf23ec68b55251db14e8658d17d9 100644 (file)
@@ -118,6 +118,10 @@ void MainWindow_configureMainWindow(entity me)
        i.configureDialog(i);
        me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
 
+       i = spawnXonoticHUDCenterprintDialog();
+       i.configureDialog(i);
+       me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
+
        me.advancedDialog = i = spawnXonoticAdvancedDialog();
        i.configureDialog(i);
        me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
index c95396332f45106f404c68c2c549dc56b71f6a44..587b1ec54cef0cac9c4be7447d1961d89c67a974 100644 (file)
@@ -8,7 +8,6 @@ float arena_roundbased;
 entity spawnqueue_first;
 entity spawnqueue_last;
 entity champion;
-string champion_name;
 float warmup;
 float ca_players;
 float required_ca_players;
@@ -134,7 +133,7 @@ void reset_map(float dorespawn)
        }
 
        if(g_keyhunt)
-               kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round+(game_starttime - time), "", kh_StartRound);
+               kh_Controller_SetThink_NoMsg(autocvar_g_balance_keyhunt_delay_round+(game_starttime - time), kh_StartRound);
 
        if(g_arena)
        if(champion && champion.classname == "player" && player_count > 1)
@@ -204,15 +203,12 @@ float roundStartTime_prev; // prevent networkspam
 void Arena_Warmup()
 {
        float f;
-       string msg;
     entity e;
 
        if((!g_arena && !g_ca && !g_freezetag) || (g_arena && !arena_roundbased) || (time < game_starttime))
                return;
 
        f = ceil(warmup - time);
-       if(f > 0)
-               champion = world; // this is done because a if(champion) will not execute if champion = world
 
        allowed_to_spawn = 0;
 
@@ -221,18 +217,17 @@ void Arena_Warmup()
        if(ca_players < required_ca_players)
                allowed_to_spawn = 1;
 
-       msg = NEWLINES;
        if(time < warmup && !inWarmupStage)
        {
                if (g_ca)
                        allowed_to_spawn = 1;
                if(champion && g_arena)
-                       msg = strcat("The Champion is ", champion_name, "^7\n");
-                       //centerprint(self, strcat(msg, "The Champion is ", champion.netname, "^7\n"));
+               {
+                       FOR_EACH_PLAYER(e)
+                               centerprint(e, strcat("The Champion is ", champion.netname));
+               }
 
                if(f != roundStartTime_prev) {
-                       msg = strcat(msg, "Round will start in ", ftos(f),"\n");
-                       //centerprint(self, strcat("Round will start in ", ftos(f),"\n"));
                        roundStartTime_prev = f;
                        if(f == 5)
                                Announce("prepareforbattle");
@@ -243,8 +238,8 @@ void Arena_Warmup()
                        else if(f == 1)
                                Announce("1");
 
-            FOR_EACH_PLAYER(e)
-                centerprint(e, msg);
+                       FOR_EACH_PLAYER(e)
+                               Send_CSQC_Centerprint_Generic(e, CPID_ROUND_STARTING, "Round will start in %d", 1, f);
                }
 
                if (g_arena) {
@@ -256,12 +251,12 @@ void Arena_Warmup()
                        self.movement = '0 0 0';
                }
        }
-
        else if(f > -1 && f != roundStartTime_prev)
        {
                roundStartTime_prev = f;
                Announce("begin");
-               centerprint(self, "^1Begin!\n");
+               FOR_EACH_PLAYER(e)
+                       Send_CSQC_Centerprint_Generic(e, CPID_ROUND_STARTING, "^1Begin!", 1, 0);
 
                if(g_ca) {
                        ca_players = 0;
@@ -272,7 +267,12 @@ void Arena_Warmup()
 
         if(self.classname == "player" && self.health > 0 && self.movetype == MOVETYPE_NONE)
             self.movetype = MOVETYPE_WALK;
+
        }
+
+       // clear champion to avoid centerprinting again the champion msg
+       if (champion)
+               champion = world;
 }
 
 void count_spawned_players()
@@ -371,6 +371,7 @@ void count_alive_players()
  *
  * Gets called in StartFrame()
  */
+float warntime;
 void Spawnqueue_Check()
 {
        count_spawned_players();
@@ -388,20 +389,20 @@ void Spawnqueue_Check()
                        reset_map(TRUE);
                }
                else if(ca_players < required_ca_players) {
-                       FOR_EACH_PLAYER(self)
-                               centerprint(self, strcat("^1Need at least 1 player in each team to play CA", "^7\n"));
+                       if (time > warntime)
+                       {
+                               FOR_EACH_PLAYER(self)
+                                       Send_CSQC_Centerprint_Generic(self, CPID_ROUND_STARTING, "^1Need at least 1 player in each team to play CA", 2, 0);
+                               warntime = time + 1;
+                       }
                        return;
                }
                else if(!next_round) {
                        if((redspawned && !bluespawned) || (bluespawned && !redspawned)) {
                                next_round = time + 5;
-                               champion = find(world, classname, "player");
-                               if(champion_name)
-                                       strunzone(champion_name);
-                               champion_name = strzone(champion.netname);
                        }
                        else if((!redspawned && !bluespawned) || time - warmup > autocvar_g_ca_round_timelimit) {
-                               FOR_EACH_CLIENT(self) centerprint(self, strcat("^7Round tied.", "^7\n"));
+                               FOR_EACH_CLIENT(self) centerprint(self, "^7Round tied");
                                next_round = time + 5;
                        }
 
@@ -411,14 +412,14 @@ void Spawnqueue_Check()
                        if(redalive && !bluealive)
                        {
                                play2all("ctf/red_capture.wav");
-                               FOR_EACH_CLIENT(self) centerprint(self, "^1 RED ^7team wins the round.\n");
+                               FOR_EACH_CLIENT(self) centerprint(self, "^1RED ^7team wins the round");
                                TeamScore_AddToTeam(COLOR_TEAM1, ST_SCORE, +1);
                                stopalivecheck = TRUE;
                        }
                        else if(bluealive && !redalive)
                        {
                                play2all("ctf/blue_capture.wav");
-                               FOR_EACH_CLIENT(self) centerprint(self, "^4 BLUE ^7team wins the round.\n");
+                               FOR_EACH_CLIENT(self) centerprint(self, "^4BLUE ^7team wins the round");
                                TeamScore_AddToTeam(COLOR_TEAM2, ST_SCORE, +1);
                                stopalivecheck = TRUE;
                        }
index ef54b1d38f57a0126ecf231aab0194b31ad603b3..cf0198b4c54aa83d0650832286014c49521f6a5a 100644 (file)
@@ -64,7 +64,7 @@ void  makestatic (entity e)                                                           = #69;
 void   changelevel (string s)                                                          = #70;
 
 void   cvar_set (string var, string val)                                               = #72;
-//void(entity client, string s) centerprint = #73;
+void(entity client, string s) centerprint = #73;
 void   ambientsound (vector pos, string samp, float vol, float atten)                  = #74;
 string precache_model2 (string s)                                                      = #75;
 string precache_sound2 (string s)                                                      = #76;
index 9a36546716d6dc644512e2536a1f449791be55c8..923950b5071cd4084dff6e3b3750f61560822784 100644 (file)
@@ -108,7 +108,7 @@ void CampaignPreInit()
 
        title = campaign_shortdesc[0];
        title = strzone(strcat("Level ", ftos(campaign_level + 1), ": ", title));
-       campaign_message = strzone(strcat("\n\n\n\n\n\n\n\n\n\n^1\n", title, "\n^3\n", campaign_longdesc[0], "\n\n^1press jump to enter the game"));
+       campaign_message = strzone(strcat(title, "\n^3\n", campaign_longdesc[0], "\n\n^1press jump to enter the game"));
        strunzone(title);
 }
 
index 5b9c8d907eab2796fef9b546761472e28b32f450..3ccd515fc297505496965905a877bfdbcd665d92 100644 (file)
@@ -614,6 +614,9 @@ void PutObserverInServer (void)
        DropAllRunes(self);
        MUTATOR_CALLHOOK(MakePlayerObserver);
 
+       if (g_minstagib)
+               minstagib_stop_countdown();
+
        Portal_ClearAll(self);
 
        if(self.alivetime)
@@ -1318,17 +1321,6 @@ void KillIndicator_Think()
                {
                        if(self.cnt <= 10)
                                AnnounceTo(self.owner, strcat(ftos(self.cnt), ""));
-                       if(self.owner.killindicator_teamchange)
-                       {
-                               if(self.owner.killindicator_teamchange == -1)
-                                       centerprint(self.owner, strcat("Changing team in ", ftos(self.cnt), " seconds"));
-                               else if(self.owner.killindicator_teamchange == -2)
-                                       centerprint(self.owner, strcat("Spectating in ", ftos(self.cnt), " seconds"));
-                               else
-                                       centerprint(self.owner, strcat("Changing to ", ColoredTeamName(self.owner.killindicator_teamchange), " in ", ftos(self.cnt), " seconds"));
-                       }
-                       else
-                               centerprint(self.owner, strcat("^1Suicide in ", ftos(self.cnt), " seconds"));
                }
                self.nextthink = time + 1;
                self.cnt -= 1;
@@ -1399,14 +1391,35 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2
        if(self.killindicator)
        {
                if(targetteam == 0) // just die
+               {
                        self.killindicator.colormod = '0 0 0';
+                       if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(self.killindicator.cnt > 0)
+                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "^1Suicide in %d seconds", 1, self.killindicator.cnt);
+               }
                else if(targetteam == -1) // auto
+               {
                        self.killindicator.colormod = '0 1 0';
+                       if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(self.killindicator.cnt > 0)
+                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "Changing team in %d seconds", 1, self.killindicator.cnt);
+               }
                else if(targetteam == -2) // spectate
+               {
                        self.killindicator.colormod = '0.5 0.5 0.5';
+                       if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(self.killindicator.cnt > 0)
+                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "Spectating in %d seconds", 1, self.killindicator.cnt);
+               }
                else
+               {
                        self.killindicator.colormod = TeamColor(targetteam);
+                       if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(self.killindicator.cnt > 0)
+                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, strcat("Changing to ", ColoredTeamName(targetteam), " in %d seconds"), 1, self.killindicator.cnt);
+               }
        }
+
 }
 
 void ClientKill (void)
@@ -1677,8 +1690,6 @@ void ClientConnect (void)
 
        bprint("\n");
 
-       self.welcomemessage_time = 0;
-
        stuffcmd(self, strcat(clientstuff, "\n"));
        stuffcmd(self, strcat("exec maps/", mapname, ".cfg\n"));
        stuffcmd(self, "cl_particles_reloadeffects\n");
@@ -1792,6 +1803,9 @@ void ClientConnect (void)
                set_dom_state(self);
 
        CheatInitClient();
+
+       if(!autocvar_g_campaign)
+               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), autocvar_welcome_message_time, 0);
 }
 
 /*
@@ -1990,47 +2004,6 @@ void play_countdown(float finished, string samp)
                                sound (self, CH_INFO, samp, VOL_BASE, ATTN_NORM);
 }
 
-/**
- * When sv_timeout is used this function returs strings like
- * "Timeout begins in 2 seconds!\n" or "Timeout ends in 23 seconds!\n".
- * Called by centerprint functions
- * @param addOneSecond boolean, set to 1 if the welcome-message centerprint asks for the text
- */
-string getTimeoutText(float addOneSecond) {
-       if (!autocvar_sv_timeout || !timeoutStatus)
-               return "";
-
-       local string retStr;
-       if (timeoutStatus == 1) {
-               if (addOneSecond == 1) {
-                       retStr = strcat("Timeout begins in ", ftos(remainingLeadTime + 1), " seconds!\n");
-               }
-               else {
-                       retStr = strcat("Timeout begins in ", ftos(remainingLeadTime), " seconds!\n");
-               }
-               return retStr;
-       }
-       else if (timeoutStatus == 2) {
-               if (addOneSecond) {
-                       retStr = strcat("Timeout ends in ", ftos(remainingTimeoutTime + 1), " seconds!\n");
-                       //don't show messages like "Timeout ends in 0 seconds"...
-                       if ((remainingTimeoutTime + 1) > 0)
-                               return retStr;
-                       else
-                               return "";
-               }
-               else {
-                       retStr = strcat("Timeout ends in ", ftos(remainingTimeoutTime), " seconds!\n");
-                       //don't show messages like "Timeout ends in 0 seconds"...
-                       if (remainingTimeoutTime > 0)
-                               return retStr;
-                       else
-                               return "";
-               }
-       }
-       else return "";
-}
-
 void player_powerups (void)
 {
        // add a way to see what the items were BEFORE all of these checks for the mutator hook
@@ -2499,7 +2472,8 @@ void LeaveSpectatorMode()
                                bprint ("^4", self.netname, "^4 is playing now\n");
 
                        if(!autocvar_g_campaign)
-                               centerprint(self,""); // clear MOTD
+                       if (time < self.jointime + autocvar_welcome_message_time)
+                               Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD); // clear MOTD
 
                        return;
                } else {
@@ -2512,7 +2486,7 @@ void LeaveSpectatorMode()
        }
        else {
                //player may not join because of g_maxplayers is set
-               centerprint_atprio(self, CENTERPRIO_MAPVOTE, PREVENT_JOIN_TEXT);
+               centerprint(self, PREVENT_JOIN_TEXT);
        }
 }
 
@@ -2563,11 +2537,9 @@ void ObserverThink()
 {
        if (self.flags & FL_JUMPRELEASED) {
                if (self.BUTTON_JUMP && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.flags |= FL_SPAWNING;
                } else if(self.BUTTON_ATCK && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        if(SpectateNext() == 1) {
                                self.classname = "spectator";
@@ -2584,18 +2556,15 @@ void ObserverThink()
                        }
                }
        }
-       PrintWelcomeMessage(self);
 }
 
 void SpectatorThink()
 {
        if (self.flags & FL_JUMPRELEASED) {
                if (self.BUTTON_JUMP && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.flags |= FL_SPAWNING;
                } else if(self.BUTTON_ATCK) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        if(SpectateNext() == 1) {
                                self.classname = "spectator";
@@ -2604,7 +2573,6 @@ void SpectatorThink()
                                PutClientInServer();
                        }
                } else if (self.BUTTON_ATCK2) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.classname = "observer";
                        PutClientInServer();
@@ -2626,7 +2594,6 @@ void SpectatorThink()
                        PutObserverInServer();
        }
 
-       PrintWelcomeMessage(self);
        self.flags |= FL_CLIENT | FL_NOTARGET;
 }
 
@@ -2662,6 +2629,7 @@ Called every frame for each client before the physics are run
 void() ctf_setstatus;
 void() nexball_setstatus;
 .float items_added;
+.float motd_actived_time; // used for both motd and campaign_message
 void PlayerPreThink (void)
 {
        WarpZone_PlayerPhysics_FixVAngle();
@@ -2740,14 +2708,46 @@ void PlayerPreThink (void)
                PlayerUseKey();
        self.usekeypressed = self.BUTTON_USE;
 
+       if (self.motd_actived_time == 0) {
+               if (autocvar_g_campaign) {
+                       if (self.classname == "player" && self.BUTTON_INFO) {
+                               self.motd_actived_time = time;
+                               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, campaign_message, -1, 0);
+                       }
+               } else {
+                       if ((self.classname == "player" || time - self.jointime > autocvar_welcome_message_time) && self.BUTTON_INFO) {
+                               self.motd_actived_time = time;
+                               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), -1, 0);
+                       }
+               }
+       } else { // showing MOTD or campaign message
+               if (autocvar_g_campaign) {
+                       if (self.classname == "player") {
+                               if (self.BUTTON_INFO)
+                                       self.motd_actived_time = time;
+                               else if (time - self.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
+                                       self.motd_actived_time = 0;
+                                       Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD);
+                               }
+                       }
+               } else {
+                       if (self.classname == "player" || (time - self.jointime) > autocvar_welcome_message_time) {
+                               if (self.BUTTON_INFO)
+                                       self.motd_actived_time = time;
+                               else if (time - self.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
+                                       self.motd_actived_time = 0;
+                                       Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD);
+                               }
+                       }
+               }
+       }
+
        if(self.classname == "player") {
 //             if(self.netname == "Wazat")
 //                     bprint(self.classname, "\n");
 
                CheckRules_Player();
 
-               PrintWelcomeMessage(self);
-
                if (intermission_running)
                {
                        IntermissionThink ();   // otherwise a button could be missed between
@@ -2803,6 +2803,9 @@ void PlayerPreThink (void)
                        player_powerups();
                }
 
+               if (g_minstagib)
+                       minstagib_ammocheck();
+
                if (self.deadflag != DEAD_NO)
                {
                        float button_pressed, force_respawn;
@@ -2850,6 +2853,8 @@ void PlayerPreThink (void)
                        }
                        return;
                }
+               // FIXME from now on self.deadflag is always 0 (and self.health is never < 1)
+               // so (self.deadflag == DEAD_NO) is always true in the code below
 
                if(g_touchexplode)
                if(time > self.touchexplode_time)
@@ -2961,9 +2966,6 @@ void PlayerPreThink (void)
                if(frametime)
                        player_anim();
 
-               if (g_minstagib)
-                       minstagib_ammocheck();
-
                if(g_ctf)
                        ctf_setstatus();
 
@@ -3090,7 +3092,21 @@ void PlayerPostThink (void)
        {
                // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero).
                float timeleft;
+               if (time - self.parm_idlesince < 1) // instead of (time == self.parm_idlesince) to support sv_maxidle <= 10
+               {
+                       if(self.idlekick_lasttimeleft)
+                       {
+                               Send_CSQC_Centerprint_Generic_Expire(self, CPID_DISCONNECT_IDLING);
+                               self.idlekick_lasttimeleft = 0;
+                       }
+                       return;
+               }
                timeleft = ceil(sv_maxidle - (time - self.parm_idlesince));
+               if(timeleft == min(10, sv_maxidle - 1)) // - 1 to support sv_maxidle <= 10
+               {
+                       if(!self.idlekick_lasttimeleft)
+                               Send_CSQC_Centerprint_Generic(self, CPID_DISCONNECT_IDLING, "^3Stop idling!\n^3Disconnecting in %d seconds...", 1, timeleft);
+               }
                if(timeleft <= 0)
                {
                        bprint("^3", self.netname, "^3 was kicked for idling.\n");
@@ -3101,16 +3117,9 @@ void PlayerPostThink (void)
                else if(timeleft <= 10)
                {
                        if(timeleft != self.idlekick_lasttimeleft)
-                       {
-                               centerprint_atprio(self, CENTERPRIO_IDLEKICK, strcat("^3Stop idling!\n^3Disconnecting in ", ftos(timeleft), "..."));
-                               AnnounceTo(self, strcat(ftos(timeleft), ""));
-                       }
-               }
-               else
-               {
-                       centerprint_expire(self, CENTERPRIO_IDLEKICK);
+                               AnnounceTo(self, ftos(timeleft));
+                       self.idlekick_lasttimeleft = timeleft;
                }
-               self.idlekick_lasttimeleft = timeleft;
        }
 
 #ifdef TETRIS
index ac08cc916a43bc343ce896afed07fe208d108825..0b6a956db913554ab688da06de9a7b615ac1c7e1 100644 (file)
@@ -237,7 +237,7 @@ void SV_ParseClientCommand(string s) {
                        }
                        else {
                                //player may not join because of g_maxplayers is set
-                               centerprint_atprio(self, CENTERPRIO_MAPVOTE, PREVENT_JOIN_TEXT);
+                               centerprint(self, PREVENT_JOIN_TEXT);
                        }
                }
        } else if( cmd == "selectteam" ) {
index a54ee6a8ac68ced40bc09fa337f0a80cf1dddcf0..0232c42f70d0002663e45a8e34f5fb2a904bf67c 100644 (file)
@@ -66,12 +66,12 @@ void ctf_captureshield_update(entity p, float dir)
                {
                        if(should)
                        {
-                               centerprint_atprio(p, CENTERPRIO_SHIELDING, "^3You are now ^4shielded^3 from the flag\n^3for ^1too many unsuccessful attempts^3 to capture.\n\n^3Make some defensive scores before trying again.");
+                               Send_CSQC_Centerprint_Generic(other, CPID_CTF_CAPTURESHIELD, "^3You are ^4shielded^3 from the flag\n^3for ^1too many unsuccessful attempts^3 to capture.\n\n^3Get some defensive scores before trying again.", 5, 0);
                                // TODO csqc notifier for this
                        }
                        else
                        {
-                               centerprint_atprio(p, CENTERPRIO_SHIELDING, "^3You are now free.\n\n^3Feel free to ^1try to capture^3 the flag again\n^3if you think you will succeed.");
+                               Send_CSQC_Centerprint_Generic(p, CPID_CTF_CAPTURESHIELD, "^3You are now free.\n\n^3Feel free to ^1try to capture^3 the flag again\n^3if you think you will succeed.", 5, 0);
                                // TODO csqc notifier for this
                        }
                        p.ctf_captureshielded = should;
@@ -88,6 +88,7 @@ float ctf_captureshield_customize()
        return TRUE;
 }
 
+.float ctf_captureshield_touch_msgtime;
 void ctf_captureshield_touch()
 {
        if not(other.ctf_captureshielded)
@@ -99,7 +100,9 @@ void ctf_captureshield_touch()
        mymid = (self.absmin + self.absmax) * 0.5;
        othermid = (other.absmin + other.absmax) * 0.5;
        Damage(other, self, self, 0, DEATH_HURTTRIGGER, mymid, normalize(othermid - mymid) * captureshield_force);
-       centerprint_atprio(other, CENTERPRIO_SHIELDING, "^3You are ^4shielded^3 from the flag\n^3for ^1too many unsuccessful attempts^3 to capture.\n\n^3Get some defensive scores before trying again.");
+       if (time - other.ctf_captureshield_touch_msgtime > 2)
+               Send_CSQC_Centerprint_Generic(other, CPID_CTF_CAPTURESHIELD, "^3You are ^4shielded^3 from the flag\n^3for ^1too many unsuccessful attempts^3 to capture.\n\n^3Get some defensive scores before trying again.", 5, 0);
+       other.ctf_captureshield_touch_msgtime = time;
 }
 
 void ctf_flag_spawnstuff()
index 2e8ba3d698064524db892edbc3145e981e3fc889..9e6a73b5e3642fe9e9ae952a9b6a318120e32ad7 100644 (file)
@@ -231,7 +231,6 @@ void weapon_defaultspawnfunc(float wpn);
 
 string w_deathtypestring;
 
-void(entity client, string s) centerprint_builtin = #73;
 .vector dest1, dest2;
 
 float gameover;
@@ -243,7 +242,6 @@ float alreadychangedlevel;
 .float runes;
 
 
-.float welcomemessage_time;
 .float version;
 
 // minstagib vars
@@ -286,7 +284,6 @@ entity timeoutHandler; //responsible for centerprinting the timeout countdowns a
 void timeoutHandler_Think();
 void evaluateTimeout();
 void evaluateTimein();
-string getTimeoutText(float addOneSecond);
 
 .float spawnshieldtime;
 
@@ -312,7 +309,6 @@ float default_weapon_alpha;
 .float() customizeentityforclient;
 .float cvar_cl_handicap;
 .float cvar_cl_playerdetailreduction;
-.float cvar_scr_centertime;
 .string cvar_g_xonoticversion;
 .string cvar_cl_weaponpriority;
 .string cvar_cl_weaponpriorities[10];
@@ -368,10 +364,6 @@ void FixClientCvars(entity e);
 
 float weaponsInMap;
 
-void centerprint_atprio(entity e, float prio, string s);
-void centerprint_expire(entity e, float prio);
-void centerprint(entity e, string s);
-
 .float respawn_countdown; // next number to count
 
 float bot_waypoints_for_items;
index 9eaf82dc42d5684be97ad93507aa5b22b376e6eb..5975adf8a8dbfa04c9f5ce0237fa5a7ee18f4c9a 100644 (file)
@@ -41,8 +41,6 @@ void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad
        Net_LinkEntity(e, FALSE, 0.2, Damage_DamageInfo_SendEntity);
 }
 
-#define DAMAGE_CENTERPRINT_SPACER NEWLINES
-
 float checkrules_firstblood;
 
 float yoda;
@@ -643,7 +641,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                        if (targ.armorvalue && (deathtype == WEP_MINSTANEX) && damage)
                        {
                                targ.armorvalue -= 1;
-                               centerprint(targ, strcat(DAMAGE_CENTERPRINT_SPACER, "^3Remaining extra lives: ",ftos(targ.armorvalue)));
+                               centerprint(targ, strcat("^3Remaining extra lives: ",ftos(targ.armorvalue)));
                                damage = 0;
                                targ.hitsound += 1;
                                attacker.hitsound += 1; // TODO change this to a future specific hitsound for armor hit
@@ -655,7 +653,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                                if (targ != attacker)
                                {
                                        if ((targ.health >= 1) && (targ.classname == "player"))
-                                               centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, "Secondary fire inflicts no damage!"));
+                                               centerprint(attacker, "Secondary fire inflicts no damage!");
                                        force = '0 0 0';
                                        // keep mirrorforce
                                        attacker = targ;
@@ -899,7 +897,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                        if(attacker.armorvalue > 0)
                        {
                                attacker.armorvalue = attacker.armorvalue - 1;
-                               centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, "^3Remaining extra lives: ",ftos(attacker.armorvalue)));
+                               centerprint(attacker, strcat("^3Remaining extra lives: ",ftos(attacker.armorvalue)));
                                attacker.hitsound += 1;
                        }
                        mirrordamage = 0;
index 9a3533f4cdd6ca514433d2cba6f9c00bbc01413e..82290cf540bf399fd7c8c7c10dbc0ba14a031902 100644 (file)
@@ -101,15 +101,13 @@ void fteqcc_testbugs()
  * players. Also plays reminder sounds.
  */
 void timeoutHandler_Think() {
-       local string timeStr;
        local entity plr;
        if (timeoutStatus == 1) {
                if (remainingLeadTime > 0) {
                        //centerprint the information to every player
-                       timeStr = getTimeoutText(0);
                        FOR_EACH_REALCLIENT(plr) {
                                if(plr.classname == "player") {
-                                       centerprint_atprio(plr, CENTERPRIO_SPAM, timeStr);
+                                       Send_CSQC_Centerprint_Generic(plr, CPID_TIMEOUT_COUNTDOWN, "Timeout begins in %d seconds!", 1, remainingLeadTime);
                                }
                        }
                        remainingLeadTime -= 1;
@@ -133,10 +131,9 @@ void timeoutHandler_Think() {
        }
        else if (timeoutStatus == 2) {
                if (remainingTimeoutTime > 0) {
-                       timeStr = getTimeoutText(0);
                        FOR_EACH_REALCLIENT(plr) {
                                if(plr.classname == "player") {
-                                       centerprint_atprio(plr, CENTERPRIO_SPAM, timeStr);
+                                       Send_CSQC_Centerprint_Generic(plr, CPID_TIMEOUT_COUNTDOWN, "Timeout ends in %d seconds!", 1, remainingTimeoutTime);
                                }
                        }
                        if(remainingTimeoutTime == autocvar_sv_timeout_resumetime) { //play a warning sound when only <sv_timeout_resumetime> seconds are left
@@ -156,7 +153,7 @@ void timeoutHandler_Think() {
                        //get rid of the countdown message
                        FOR_EACH_REALCLIENT(plr) {
                                if(plr.classname == "player") {
-                                       centerprint_atprio(plr, CENTERPRIO_SPAM, "");
+                                       Send_CSQC_Centerprint_Generic_Expire(plr, CPID_TIMEOUT_COUNTDOWN);
                                }
                        }
                        remove(self);
@@ -167,7 +164,7 @@ void timeoutHandler_Think() {
        else if (timeoutStatus == 0) { //if a player called the resumegame command (which set timeoutStatus to 0 already)
                FOR_EACH_REALCLIENT(plr) {
                        if(plr.classname == "player") {
-                               centerprint_atprio(plr, CENTERPRIO_SPAM, "");
+                               Send_CSQC_Centerprint_Generic_Expire(plr, CPID_TIMEOUT_COUNTDOWN);
                        }
                }
                remove(self);
index 9fce6368c798e2981b14b657d431eecafc0c4778..8449157705c9c3a38dcad3ccc54c3c8e12a3130f 100644 (file)
@@ -815,7 +815,7 @@ void GameCommand(string command)
                                }
                                else
                                {
-                                       centerprint_atprio(client, CENTERPRIO_ADMIN, strcat("^3", admin_name(), ":\n\n^7", argv(2)));
+                                       centerprint(client, strcat("^3", admin_name(), ":\n\n^7", argv(2)));
                                        sprint(client, strcat("\{1}\{13}^3", admin_name(), "^7: ", argv(2), "\n"));
                                }
                                print("Message sent to ", client.netname, "\n");
index b669b041f51f765b10c8875b3e2d5c89d8fe6308..b94238036bfab813cd349ccac93b9fe8972339e4 100644 (file)
@@ -579,7 +579,6 @@ void GetCvars(float f)
        MUTATOR_CALLHOOK(GetCvars);
        GetCvars_handleFloat(s, f, autoswitch, "cl_autoswitch");
        GetCvars_handleFloat(s, f, cvar_cl_playerdetailreduction, "cl_playerdetailreduction");
-       GetCvars_handleFloat(s, f, cvar_scr_centertime, "scr_centertime");
        GetCvars_handleString(s, f, cvar_g_xonoticversion, "g_xonoticversion");
        GetCvars_handleFloat(s, f, cvar_cl_handicap, "cl_handicap");
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriority, "cl_weaponpriority", W_FixWeaponOrder_ForceComplete_AndBuildImpulseList);
@@ -718,46 +717,6 @@ float NumberToTeamNumber(float number)
        return -1;
 }
 
-#define CENTERPRIO_POINT 1
-#define CENTERPRIO_SPAM 2
-#define CENTERPRIO_VOTE 4
-#define CENTERPRIO_NORMAL 5
-#define CENTERPRIO_SHIELDING 7
-#define CENTERPRIO_MAPVOTE 9
-#define CENTERPRIO_IDLEKICK 50
-#define CENTERPRIO_ADMIN 99
-.float centerprint_priority;
-.float centerprint_expires;
-void centerprint_atprio(entity e, float prio, string s)
-{
-    if (intermission_running)
-        if (prio < CENTERPRIO_MAPVOTE)
-            return;
-    if (time > e.centerprint_expires)
-        e.centerprint_priority = 0;
-    if (prio >= e.centerprint_priority)
-    {
-        e.centerprint_priority = prio;
-        if (timeoutStatus == 2)
-            e.centerprint_expires = time + (e.cvar_scr_centertime * TIMEOUT_SLOWMO_VALUE);
-        else
-            e.centerprint_expires = time + e.cvar_scr_centertime;
-        centerprint_builtin(e, s);
-    }
-}
-void centerprint_expire(entity e, float prio)
-{
-    if (prio == e.centerprint_priority)
-    {
-        e.centerprint_priority = 0;
-        centerprint_builtin(e, "");
-    }
-}
-void centerprint(entity e, string s)
-{
-    centerprint_atprio(e, CENTERPRIO_NORMAL, s);
-}
-
 // decolorizes and team colors the player name when needed
 string playername(entity p)
 {
@@ -1700,6 +1659,30 @@ void precache()
 #define WRITESPECTATABLE_MSG_ONE(statement) WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement)
 #define WRITESPECTATABLE(msg,statement) if(msg == MSG_ONE) { WRITESPECTATABLE_MSG_ONE(statement); } else statement float WRITESPECTATABLE_workaround = 0
 
+
+void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num)
+{
+       if (clienttype(e) == CLIENTTYPE_REAL)
+       {
+               msg_entity = e;
+               WRITESPECTATABLE_MSG_ONE({
+                       WriteByte(MSG_ONE, SVC_TEMPENTITY);
+                       WriteByte(MSG_ONE, TE_CSQC_NOTIFY);
+                       WriteByte(MSG_ONE, CSQC_CENTERPRINT_GENERIC);
+                       WriteByte(MSG_ONE, id);
+                       WriteString(MSG_ONE, s);
+                       if (id != 0 && s != "")
+                       {
+                               WriteByte(MSG_ONE, duration);
+                               WriteByte(MSG_ONE, countdown_num);
+                       }
+               });
+       }
+}
+void Send_CSQC_Centerprint_Generic_Expire(entity e, float id)
+{
+       Send_CSQC_Centerprint_Generic(e, id, "", 1, 0);
+}
 // WARNING: this kills the trace globals
 #define EXACTTRIGGER_TOUCH if(WarpZoneLib_ExactTrigger_Touch()) return
 #define EXACTTRIGGER_INIT  WarpZoneLib_ExactTrigger_Init()
index e71c2d7ef6ecd20f04faa06627c041f7673ed225..8d3511eceda0750e74266d5649133b69f9c15e84 100644 (file)
@@ -127,7 +127,7 @@ void ka_TouchEvent() // runs any time that the ball comes in contact with someth
        // messages and sounds
        Send_KillNotification(other.netname, "", "", KA_PICKUPBALL, MSG_KA);
        WriteByte(MSG_BROADCAST, SVC_CENTERPRINT);
-       WriteString(MSG_BROADCAST, strcat("\n\n", other.netname, "^7 has picked up the ball!\n"));
+       WriteString(MSG_BROADCAST, strcat(other.netname, "^7 has picked up the ball!"));
        sound(self.owner, CH_TRIGGER, "keepaway/pickedup.wav", VOL_BASE, ATTN_NONE); // ATTN_NONE (it's a sound intended to be heard anywhere) 
        
        // scoring
@@ -169,8 +169,8 @@ void ka_DropEvent(entity plyr) // runs any time that a player is supposed to los
        // messages and sounds
        Send_KillNotification(plyr.netname, "", "", KA_DROPBALL, MSG_KA);
        WriteByte(MSG_BROADCAST, SVC_CENTERPRINT);
-       WriteString(MSG_BROADCAST, strcat("\n\n", plyr.netname, "^7 has dropped the ball!\n"));
-       sound(plyr, CH_TRIGGER, "keepaway/dropped.wav", VOL_BASE, ATTN_NONE);   // ATTN_NONE (it's a sound intended to be heard anywhere) 
+       WriteString(MSG_BROADCAST, strcat(plyr.netname, "^7 has dropped the ball!"));
+       sound(other, CH_TRIGGER, "keepaway/dropped.wav", VOL_BASE, ATTN_NONE);  // ATTN_NONE (it's a sound intended to be heard anywhere) 
        
        // scoring
        // PlayerScore_Add(plyr, SP_KEEPAWAY_DROPS, 1); Not anymore, this is 100% the same as pickups and is useless.
@@ -216,7 +216,7 @@ MUTATOR_HOOKFUNCTION(ka_Scoring)
                }
                else if(!frag_attacker.ballcarried)
                        if(autocvar_g_keepaway_noncarrier_warn)
-                               centerprint_atprio(frag_attacker, (CENTERPRIO_SPAM + 5), "Killing people while you don't have the ball gives no points!");
+                               centerprint(frag_attacker, "Killing people while you don't have the ball gives no points!");
 
                if(frag_attacker.ballcarried) // add to amount of kills while ballcarrier
                        PlayerScore_Add(frag_attacker, SP_SCORE, autocvar_g_keepaway_score_killac);
index decada0312d4536537d9ab519b5b46cb822a04c8..d3f4fdc87e8fa328bfc87dd000f79c6ccbe1e38d 100644 (file)
@@ -58,6 +58,7 @@ float kh_interferemsg_time, kh_interferemsg_team;
 .float kh_dropperteam;
 .entity kh_previous_owner;
 .float kh_previous_owner_playerid;
+.float kh_cp_duration;
 
 string kh_sound_capture = "kh/capture.wav";
 string kh_sound_destroy = "kh/destroy.wav";
@@ -121,7 +122,7 @@ void kh_update_state()
 
 
 var kh_Think_t kh_Controller_Thinkfunc;
-void kh_Controller_SetThink(float t, string msg, kh_Think_t func)  // runs occasionaly
+void kh_Controller_SetThink(float t, string msg, float centerprint_duration, kh_Think_t func)  // runs occasionaly
 {
        kh_Controller_Thinkfunc = func;
        kh_controller.cnt = ceil(t);
@@ -130,10 +131,17 @@ void kh_Controller_SetThink(float t, string msg, kh_Think_t func)  // runs occas
        if(msg == "")
                kh_Controller_Waitmsg = "";
        else
+       {
+               kh_controller.kh_cp_duration = centerprint_duration;
                kh_Controller_Waitmsg = strzone(msg);
+       }
        if(t == 0)
                kh_controller.nextthink = time; // force
 }
+void kh_Controller_SetThink_NoMsg(float t, kh_Think_t func)  // runs occasionaly
+{
+       kh_Controller_SetThink(t, "", 0, func);
+}
 
 void kh_Controller_Think()  // called a lot
 {
@@ -154,7 +162,7 @@ void kh_Controller_Think()  // called a lot
 
                        FOR_EACH_PLAYER(e)
                                if(clienttype(e) == CLIENTTYPE_REAL)
-                                       centerprint_atprio(e, CENTERPRIO_SPAM, s);
+                                       Send_CSQC_Centerprint_Generic(e, CPID_KH_MSG, s, self.kh_cp_duration, 0);
                }
                self.cnt -= 1;
        }
@@ -486,7 +494,7 @@ void kh_FinishRound()  // runs when a team captures the keys
                kh_Key_Remove(key);
        kh_no_radar_circles = FALSE;
 
-       kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, "Round starts in ", kh_StartRound);
+       kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, "Round starts in ", 1, kh_StartRound);
 }
 
 void kh_WinnerTeam(float teem)  // runs when a team wins
@@ -685,11 +693,11 @@ void kh_Key_Think()  // runs all the time
                {
                        if(head.team == kh_interferemsg_team)
                                if(head.kh_next)
-                                       centerprint(head, "All keys are in your team's hands!\n\nMeet the other key carriers ^1NOW^7!");
+                                       Send_CSQC_Centerprint_Generic(head, CPID_KH_MSG, "All keys are in your team's hands!\n\nMeet the other key carriers ^1NOW^7!", 0, 0);
                                else
-                                       centerprint(head, "All keys are in your team's hands!\n\nHelp the key carriers to meet!");
+                                       Send_CSQC_Centerprint_Generic(head, CPID_KH_MSG, "All keys are in your team's hands!\n\nHelp the key carriers to meet!", 0, 0);
                        else
-                               centerprint(head, strcat("All keys are in the ", ColoredTeamName(kh_interferemsg_team), "^7's hands!\n\nInterfere ^1NOW^7!"));
+                               Send_CSQC_Centerprint_Generic(head, CPID_KH_MSG, strcat("All keys are in the ", ColoredTeamName(kh_interferemsg_team), "^7's hands!\n\nInterfere ^1NOW^7!"), 0, 0);
                }
        }
 
@@ -862,15 +870,15 @@ void kh_WaitForPlayers()  // delay start of the round until enough players are p
 
        if(time < game_starttime)
        {
-               kh_Controller_SetThink(game_starttime - time + 0.1, "", kh_WaitForPlayers);
+               kh_Controller_SetThink_NoMsg(game_starttime - time + 0.1, kh_WaitForPlayers);
                return;
        }
 
        teams_missing = kh_CheckEnoughPlayers();
        if(teams_missing == "")
-               kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, "Round starts in ", kh_StartRound);
+               kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, "Round starts in ", 1, kh_StartRound);
        else
-               kh_Controller_SetThink(1, strcat("Waiting for players to join...\n\nNeed active players for: ", teams_missing), kh_WaitForPlayers);
+               kh_Controller_SetThink(1, strcat("Waiting for players to join...\n\nNeed active players for: ", teams_missing), -1, kh_WaitForPlayers);
 }
 
 void kh_EnableTrackingDevice()  // runs after each round
@@ -879,7 +887,7 @@ void kh_EnableTrackingDevice()  // runs after each round
 
        FOR_EACH_PLAYER(player)
                if(clienttype(player) == CLIENTTYPE_REAL)
-                       centerprint_expire(player, CENTERPRIO_SPAM);
+                       Send_CSQC_Centerprint_Generic_Expire(player, CPID_KH_MSG);
 
        kh_tracking_enabled = TRUE;
 }
@@ -892,20 +900,20 @@ void kh_StartRound()  // runs at the start of each round
 
        if(time < game_starttime)
        {
-               kh_Controller_SetThink(game_starttime - time + 0.1, "", kh_WaitForPlayers);
+               kh_Controller_SetThink_NoMsg(game_starttime - time + 0.1, kh_WaitForPlayers);
                return;
        }
 
        teams_missing = kh_CheckEnoughPlayers();
        if(teams_missing != "")
        {
-               kh_Controller_SetThink(1, strcat("Waiting for players to join...\n\nNeed active players for: ", teams_missing), kh_WaitForPlayers);
+               kh_Controller_SetThink(1, strcat("Waiting for players to join...\n\nNeed active players for: ", teams_missing), -1, kh_WaitForPlayers);
                return;
        }
 
        FOR_EACH_PLAYER(player)
                if(clienttype(player) == CLIENTTYPE_REAL)
-                       centerprint_expire(player, CENTERPRIO_SPAM);
+                       Send_CSQC_Centerprint_Generic_Expire(player, CPID_KH_MSG);
 
        for(i = 0; i < kh_teams; ++i)
        {
@@ -925,7 +933,7 @@ void kh_StartRound()  // runs at the start of each round
        }
 
        kh_tracking_enabled = FALSE;
-       kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_tracking, "Scanning frequency range...", kh_EnableTrackingDevice);
+       kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_tracking, "Scanning frequency range...", -1, kh_EnableTrackingDevice);
 }
 
 float kh_HandleFrags(entity attacker, entity targ, float f)  // adds to the player score
@@ -977,7 +985,7 @@ void kh_Initialize()  // sets up th KH environment
        // make a KH entity for controlling the game
        kh_controller = spawn();
        kh_controller.think = kh_Controller_Think;
-       kh_Controller_SetThink(0, "", kh_WaitForPlayers);
+       kh_Controller_SetThink_NoMsg(0, kh_WaitForPlayers);
 
        setmodel(kh_controller, "models/keyhunt/key.md3");
        kh_key_dropped = kh_controller.modelindex;
index 71f25c3a8876d4323b739d88973243a386981659..8ee8434293669b00a15501c92612f7c1d3eedf51 100644 (file)
@@ -9,4 +9,4 @@ float kh_Key_AllOwnedByWhichTeam();
 // used by arena.qc ready-restart:
 typedef void(void) kh_Think_t;
 void kh_StartRound();
-void kh_Controller_SetThink(float t, string msg, kh_Think_t func);
+void kh_Controller_SetThink_NoMsg(float t, kh_Think_t func);
index a4131af40e8a530f223822db10df609652e6ac29..8b8ea91f36c4e077109ff917ff4358e5aea1c5a9 100644 (file)
@@ -61,10 +61,13 @@ void NIX_GiveCurrentWeapon()
                nix_weapon = nix_nextweapon;
                nix_weapon_ammo = nix_nextweapon_ammo;
                nix_nextweapon = 0;
-               nix_nextchange = time + autocvar_g_balance_nix_roundtime;
+               if (!nix_nextchange) // no round played yet?
+                       nix_nextchange = time; // start the first round now!
+               else
+                       nix_nextchange = time + autocvar_g_balance_nix_roundtime;
                //weapon_action(nix_weapon, WR_PRECACHE); // forget it, too slow
        }
-       
+
        if(nix_nextchange != self.nix_lastchange_id) // this shall only be called once per round!
        {
                self.nix_lastchange_id = nix_nextchange;
@@ -98,13 +101,13 @@ void NIX_GiveCurrentWeapon()
                if(dt >= 1 && dt <= 5)
                        self.nix_lastinfotime = -42;
                else
-                       centerprint(self, strcat("\n\n^2Active weapon: ^3", W_Name(nix_weapon)));
+                       Send_CSQC_Centerprint_Generic(self, CPID_NIX_WPNCHANGE, strcat("^2Active weapon: ^3", W_Name(nix_weapon)), 0, 0);
        }
        if(self.nix_lastinfotime != dt)
        {
                self.nix_lastinfotime = dt; // initial value 0 should count as "not seen"
                if(dt >= 1 && dt <= 5)
-                       centerprint(self, strcat("^3", ftos(dt), "^2 seconds until weapon change...\n\nNext weapon: ^3", W_Name(nix_nextweapon), "\n"));
+                       Send_CSQC_Centerprint_Generic(self, CPID_NIX_WPNCHANGE, strcat("^3%d^2 seconds until weapon change...\n\nNext weapon: ^3", W_Name(nix_nextweapon)), 1, dt);
        }
 
        if(!(self.items & IT_UNLIMITED_WEAPON_AMMO) && time > self.nix_nextincr)
@@ -229,7 +232,7 @@ MUTATOR_DEFINITION(mutator_nix)
        {
                g_nix_with_laser = autocvar_g_nix_with_laser;
 
-               nix_nextchange = time;
+               nix_nextchange = 0;
                nix_nextweapon = 0;
 
                NIX_precache();
index 99ddc018b95a08352eabb2df2a3ac8fc14b276fc..b502cac3312d051d46c4f044516f78c1d4ff80eb 100644 (file)
@@ -279,7 +279,6 @@ float Item_GiveTo(entity item, entity player)
                        {
                                pickedup = TRUE;
                                // play some cool sounds ;)
-                               centerprint(player, "\n");
                                if (clienttype(player) == CLIENTTYPE_REAL)
                                {
                                        if(player.health <= 5)
index ab8eee07534f0d1a7ab079e58d0e5bbd418ac688..c5f8988b94387f795231865cf18464cc8fb38c66 100644 (file)
@@ -450,56 +450,10 @@ string GetClientVersionMessage() {
        return versionmsg;
 }
 
-
-void PrintWelcomeMessage(entity pl)
+string getwelcomemessage(void)
 {
        string s, modifications, motd;
 
-       if(self.cvar_scr_centertime == 0) return;
-
-       if(autocvar_g_campaign)
-       {
-               if(self.classname == "player" && !self.BUTTON_INFO)
-                       return;
-       }
-       else
-       {
-               if((time - self.jointime) > autocvar_welcome_message_time && !self.BUTTON_INFO)
-                       return;
-       }
-
-       if( !(timeoutStatus >= 1) ) { //really print the WelcomeMessage to the player every frame when timeout-seconds are shown or the game is restarted, to make sure that the shown number is accurate
-               if(self.welcomemessage_time > time) return;
-               self.welcomemessage_time = time + max(0.5, self.cvar_scr_centertime * 0.6);
-       }
-
-       if(autocvar_g_campaign)
-       {
-               centerprint(pl, campaign_message);
-               return;
-       }
-
-//TODO GreEn`mArine: make the timeout-messages clientside as well (just like the ready restart countdown)!
-       if(!self.BUTTON_INFO)
-       {
-               // TODO get rid of this too
-               local string specString;
-               specString = NEWLINES;
-               //if(time < game_starttime) //also show the countdown when being a spectator
-               //      specString = strcat(specString, "\n\n^1Game starts in ", ftos(ceil(game_starttime - time)), " seconds^7");
-               //else
-               if (timeoutStatus != 0)
-                       specString = strcat(specString, "\n\n", getTimeoutText(1));
-               else
-               {
-                       if(self.classname == "player")
-                               return;
-                       goto normal;
-               }
-               return centerprint_atprio(self, CENTERPRIO_SPAM, specString);
-       }
-
-:normal
        ret_string = "";
        MUTATOR_CALLHOOK(BuildMutatorsPrettyString);
        modifications = ret_string;
@@ -536,15 +490,12 @@ void PrintWelcomeMessage(entity pl)
        local string versionmessage;
        versionmessage = GetClientVersionMessage();
 
-       s = strcat(s, NEWLINES, "This is Xonotic ", autocvar_g_xonoticversion, "\n", versionmessage);
+       s = strcat("This is Xonotic ", autocvar_g_xonoticversion, "\n", versionmessage);
        s = strcat(s, "^8\n\nmatch type is ^1", gamemode_name, "^8\n");
 
        if(modifications != "")
                s = strcat(s, "^8\nactive modifications: ^3", modifications, "^8\n");
 
-       if(timeoutStatus != 0)
-               s = strcat(s, "\n\n", getTimeoutText(1));
-
        if (g_grappling_hook)
                s = strcat(s, "\n\n^3grappling hook^8 is enabled, press 'e' to use it\n");
 
@@ -566,12 +517,9 @@ void PrintWelcomeMessage(entity pl)
        if (motd != "") {
                s = strcat(s, "\n\n^8MOTD: ^7", strreplace("\\n", "\n", motd));
        }
-       s = strcat(s, "\n");
-
-       centerprint(pl, s);
+       return s;
 }
 
-
 void SetPlayerColors(entity pl, float _color)
 {
        /*string s;
index bad3eafe40d3c78b5b1d2d6438c08537d7469e76..ebb11a64d62d7696d764e3cd935dc52d9fa91914 100644 (file)
@@ -287,7 +287,6 @@ float GameCommand_Vote(string s, entity e) {
                                VoteDialog_UpdateHighlight(1);
                                print_to(e, "^1You accepted the vote.");
                                e.vote_vote = 1;
-                               centerprint_expire(e, CENTERPRIO_VOTE);
                                if(!autocvar_sv_vote_singlecount) {
                                        VoteCount();
                                }
@@ -305,7 +304,6 @@ float GameCommand_Vote(string s, entity e) {
                                VoteDialog_UpdateHighlight(2);
                                print_to(e, "^1You rejected the vote.");
                                e.vote_vote = -1;
-                               centerprint_expire(e, CENTERPRIO_VOTE);
                                if(!autocvar_sv_vote_singlecount) {
                                        VoteCount();
                                }
@@ -323,7 +321,6 @@ float GameCommand_Vote(string s, entity e) {
                                VoteDialog_UpdateHighlight(3);
                                print_to(e, "^1You abstained from your vote.");
                                e.vote_vote = -2;
-                               centerprint_expire(e, CENTERPRIO_VOTE);
                                if(!autocvar_sv_vote_singlecount) {
                                        VoteCount();
                                }
@@ -466,7 +463,6 @@ void VoteReset() {
        FOR_EACH_CLIENT(player)
        {
                player.vote_vote = 0;
-               centerprint_expire(player, CENTERPRIO_VOTE);
        }
 
        if(votecalled)
index 54dd5a6ce8281c2c852f04dd52a7aa91d204142d..16cbdcded3778eb1bb7988991ecbeb39a11c54ec 100644 (file)
@@ -88,77 +88,80 @@ void W_MinstaNex_Attack (void)
 
 
 .float minstagib_nextthink;
-void minstagib_ammocheck (void)
+.float minstagib_needammo;
+void minstagib_stop_countdown(void)
 {
-       if (time < self.minstagib_nextthink || self.deadflag || gameover)
+       if (self.minstagib_needammo)
+       {
+               self.health = 100;
+               Send_CSQC_Centerprint_Generic_Expire(self, CPID_MINSTA_FINDAMMO);
+       }
+       self.minstagib_needammo = FALSE;
+}
+void minstagib_ammocheck(void)
+{
+       if (time < self.minstagib_nextthink)
                return;
 
-       if (self.ammo_cells <= 0)
-       if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+       if (self.deadflag || gameover || self.ammo_cells > 0 || (self.items & IT_UNLIMITED_WEAPON_AMMO))
+               minstagib_stop_countdown();
+       else
        {
+               self.minstagib_needammo = TRUE;
                if (self.health == 5)
                {
-                       centerprint(self, "you're dead now...\n");
                        Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
                        AnnounceTo(self, "terminated");
                }
                else if (self.health == 10)
                {
-                       centerprint(self, "^11^7 second left to find some ammo\n");
                        Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
                        AnnounceTo(self, "1");
                }
                else if (self.health == 20)
                {
-                       centerprint(self, "^12^7 seconds left to find some ammo\n");
                        Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
                        AnnounceTo(self, "2");
                }
                else if (self.health == 30)
                {
-                       centerprint(self, "^13^7 seconds left to find some ammo\n");
                        Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
                        AnnounceTo(self, "3");
                }
                else if (self.health == 40)
                {
-                       centerprint(self, "^14^7 seconds left to find some ammo\n");
                        Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
                        AnnounceTo(self, "4");
                }
                else if (self.health == 50)
                {
-                       centerprint(self, "^15^7 seconds left to find some ammo\n");
                        Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
                        AnnounceTo(self, "5");
                }
                else if (self.health == 60)
                {
-                       centerprint(self, "^36^7 seconds left to find some ammo\n");
                        Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
                        AnnounceTo(self, "6");
                }
                else if (self.health == 70)
                {
-                       centerprint(self, "^37^7 seconds left to find some ammo\n");
                        Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
                        AnnounceTo(self, "7");
                }
                else if (self.health == 80)
                {
-                       centerprint(self, "^38^7 seconds left to find some ammo\n");
                        Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
                        AnnounceTo(self, "8");
                }
                else if (self.health == 90)
                {
-                       centerprint(self, "^39^7 seconds left to find some ammo\n");
+                       Send_CSQC_Centerprint_Generic(self, CPID_MINSTA_FINDAMMO, "^1%d^7 seconds left to find some ammo", 1, 9);
                        Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
                        AnnounceTo(self, "9");
                }
                else if (self.health == 100)
                {
-                       centerprint(self, "get some ammo or\nyou'll be dead in ^310^7 seconds...");
+                       Send_CSQC_Centerprint_Generic(self, CPID_MINSTA_FINDAMMO, "get some ammo or\nyou'll be dead in ^3%d^7 seconds...", 1, 10);
                        Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
                        if not(self.flags & FL_GODMODE)
                                AnnounceTo(self, "10");