From c61d94c21c07060183f795a3ce2425b84e376d0a Mon Sep 17 00:00:00 2001 From: div0 Date: Fri, 6 Feb 2009 08:58:41 +0000 Subject: [PATCH] centerprint handlign in csqc (#2555668 after large cleanups) git-svn-id: svn://svn.icculus.org/nexuiz/trunk@5773 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/client/Main.qc | 5 +- data/qcsrc/client/main.qh | 2 + data/qcsrc/client/mapvoting.qc | 2 +- data/qcsrc/client/miscfunctions.qc | 4 +- data/qcsrc/client/sbar.qc | 260 ++++++++++++++++++++++------- data/qcsrc/common/campaign_file.qc | 2 +- data/qcsrc/common/util.qc | 113 +++++++++++++ data/qcsrc/common/util.qh | 7 + data/qcsrc/menu/draw.qc | 68 ++------ data/qcsrc/menu/draw.qh | 3 + data/qcsrc/menu/item/label.c | 2 +- data/qcsrc/menu/nexuiz/campaign.c | 2 +- data/qcsrc/menu/nexuiz/util.qc | 37 ---- data/qcsrc/menu/nexuiz/util.qh | 3 - data/qcsrc/server/campaign.qc | 2 +- data/qcsrc/server/cl_player.qc | 10 +- data/qcsrc/server/miscfunctions.qc | 33 ++-- data/qcsrc/server/teamplay.qc | 23 +-- 18 files changed, 380 insertions(+), 198 deletions(-) diff --git a/data/qcsrc/client/Main.qc b/data/qcsrc/client/Main.qc index 02655925d..a02edd2b8 100644 --- a/data/qcsrc/client/Main.qc +++ b/data/qcsrc/client/Main.qc @@ -807,10 +807,11 @@ void CSQC_Parse_Print(string strMessage) { print(ColorTranslateRGB(strMessage)); } -// CSQC_Parse_CenterPrint : Provides the centerprint string in the first parameter that the server provided. To execute standard behavior, simply execute cprint with the string. + +// CSQC_Parse_CenterPrint : Provides the centerprint string in the first parameter that the server provided. void CSQC_Parse_CenterPrint(string strMessage) { - cprint(ColorTranslateRGB(strMessage)); + centerprint(strMessage); } void CSQC_CheckRevision(); diff --git a/data/qcsrc/client/main.qh b/data/qcsrc/client/main.qh index c9a3b4b9b..96de33941 100644 --- a/data/qcsrc/client/main.qh +++ b/data/qcsrc/client/main.qh @@ -149,3 +149,5 @@ float camera_active; // Demo camera is active if set to TRUE float chase_active_backup; float camera_roll; vector camera_direction; + +void centerprint(string strMessage); diff --git a/data/qcsrc/client/mapvoting.qc b/data/qcsrc/client/mapvoting.qc index 07f9b4765..bf9ad9e58 100644 --- a/data/qcsrc/client/mapvoting.qc +++ b/data/qcsrc/client/mapvoting.qc @@ -22,7 +22,7 @@ string MapVote_FormatMapItem(float id, string map, float count, float maxwidth) else post = ""; maxwidth -= stringwidth(pre, FALSE) + stringwidth(post, FALSE); - map = textShortenToWidth(map, maxwidth, FALSE); + map = textShortenToWidth(map, maxwidth, stringwidth_nocolors); return strcat(pre, map, post); } diff --git a/data/qcsrc/client/miscfunctions.qc b/data/qcsrc/client/miscfunctions.qc index f648de2bc..1151c042d 100644 --- a/data/qcsrc/client/miscfunctions.qc +++ b/data/qcsrc/client/miscfunctions.qc @@ -9,7 +9,7 @@ void restartAnnouncer_Think() { countdown_rounded = floor(0.5 + countdown); if(countdown <= 0) { if (!spectatee_status) //do cprint only for players - cprint(NEWLINES, "^1Begin!"); + centerprint("^1Begin!"); sound(self, CHAN_VOICE, "announcer/robotic/begin.wav", VOL_BASEVOICE, ATTN_NONE); remove(self); @@ -17,7 +17,7 @@ void restartAnnouncer_Think() { } else { if (!spectatee_status) //do cprint only for players - cprint(NEWLINES, "^1Game starts in ", ftos(countdown_rounded), " seconds"); + centerprint(strcat("^1Game starts in ", ftos(countdown_rounded), " seconds")); if(countdown_rounded <= 3 && countdown_rounded >= 1) { sound(self, CHAN_VOICE, strcat("announcer/robotic/", ftos(countdown_rounded), ".wav"), VOL_BASEVOICE, ATTN_NONE); diff --git a/data/qcsrc/client/sbar.qc b/data/qcsrc/client/sbar.qc index 4196d33ac..f0fc80d69 100644 --- a/data/qcsrc/client/sbar.qc +++ b/data/qcsrc/client/sbar.qc @@ -661,52 +661,21 @@ string Sbar_GetField(entity pl, float field) //return "error"; } -// shamelessly stolen from menu QC :P <- as if I would steal YOUR code pfft ;) -float textLengthUpToWidth(string theText, float maxWidth, float handleColors) -{ - // STOP. - // The following function is SLOW. - // For your safety and for the protection of those around you... - // DO NOT CALL THIS AT HOME. - // No really, don't. - if(stringwidth(theText, handleColors) <= maxWidth) - return strlen(theText); // yeah! - - // binary search for right place to cut string - float left, right, middle; // this always works - left = 0; - right = strlen(theText); // this always fails - do - { - middle = floor((left + right) / 2); - if(stringwidth(substring(theText, 0, middle), handleColors) <= maxWidth) - left = middle; - else - right = middle; - } - while(left < right - 1); - - // NOTE: when color codes are involved, this binary search is, - // mathematically, BROKEN. However, it is obviously guaranteed to - // terminate, as the range still halves each time - but nevertheless, it is - // guaranteed that it finds ONE valid cutoff place (where "left" is in - // range, and "right" is outside). - - return left; -} -string textShortenToWidth(string theText, float maxWidth, float handleColors) -{ - if(stringwidth(theText, handleColors) <= maxWidth) - return theText; - else - return strcat(substring(theText, 0, textLengthUpToWidth(theText, maxWidth - stringwidth("...", handleColors), handleColors)), "..."); -} - float xmin, xmax, ymin, ymax, sbwidth; float sbar_fixscoreboardcolumnwidth_len; float sbar_fixscoreboardcolumnwidth_iconlen; float sbar_fixscoreboardcolumnwidth_marginlen; +float stringwidth_colors(string s) +{ + return stringwidth(s, TRUE); +} + +float stringwidth_nocolors(string s) +{ + return stringwidth(s, FALSE); +} + string Sbar_FixScoreboardColumnWidth(float i, string str) { float field, maxsize, j, f; @@ -719,7 +688,7 @@ string Sbar_FixScoreboardColumnWidth(float i, string str) for(j = 0; j < sbar_num_fields; ++j) if(j != i) if(sbar_field[j] != SP_SEPARATOR) maxsize -= sbar_size[j] + 1; maxsize += 1; - str = textShortenToWidth(str, maxsize, TRUE); + str = textShortenToWidth(str, maxsize, stringwidth_colors); sbar_fixscoreboardcolumnwidth_len = stringwidth(str, TRUE); } else @@ -854,6 +823,7 @@ void Sbar_PrintScoreboardItem(vector pos, entity pl, float is_self) } float lastpingstime; +float scoreboard_bottom; void Sbar_DrawScoreboard() { //float xmin, ymin, xmax, ymax; @@ -871,7 +841,7 @@ void Sbar_DrawScoreboard() sbwidth = Sbar_GetWidth(6.5 * sbar_fontsize_y); xmin = 0.5 * (vid_conwidth - sbwidth); - ymin = 20; + ymin = 45; xmax = vid_conwidth - xmin; ymax = vid_conheight - 0.2*vid_conheight; @@ -1062,10 +1032,11 @@ void Sbar_DrawScoreboard() } - pos_y += 1.5 * sbar_fontsize_y; + pos_y += 1.2 * sbar_fontsize_y; drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - sbar_fontsize_x * stringwidth(str, TRUE)), str, sbar_fontsize, 0.8, 0); sbar = sbar_save; + scoreboard_bottom = pos_y + 2 * sbar_fontsize_y; } string MakeRaceString(float cp, float mytime, float histime, float lapdelta, string hisname) @@ -1478,19 +1449,6 @@ float Sbar_WouldDrawScoreboard () return 0; } -vector Sbar_DrawNoteLine(vector offset, string s) -{ - dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0) - drawcolorcodedstring( - offset - sbar_fontsize_x * '1 0 0' * stringwidth(s, TRUE), - s, - sbar_fontsize, - sbar_alpha_fg, - 0 - ); - return offset + sbar_fontsize_y * '0 1 0'; -} - void CSQC_Strength_Timer() { float stat_items; stat_items = getstati(STAT_ITEMS); @@ -1544,6 +1502,186 @@ void CSQC_Strength_Timer() { } } +#define CENTERPRINT_MAX_LINES 30 +string centerprint_messages[CENTERPRINT_MAX_LINES]; +float centerprint_width[CENTERPRINT_MAX_LINES]; +vector centerprint_start; +float centerprint_expire; +float centerprint_num; +float centerprint_offset_hint; +vector centerprint_fontsize = '11 11 0'; + +void centerprint(string strMessage) +{ + float i, j, n, hcount; + string s; + + // delete old centerprint messages + for (i=0; i= 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; + + // TODO if we're parsing centerprints now anyway, why not word wrap them? + 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_x, stringwidth_colors); + centerprint_messages[i] = strzone(s); + centerprint_width[i] = stringwidth(s, TRUE); + ++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(cvar("con_chatpos") < 0) + havail -= (-cvar("con_chatpos") + cvar("con_chat")) * cvar("con_chatsize"); // avoid overlapping chat + + centerprint_start_x = 0; + +#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 + centerprint_start_y = + min( + max( + max(scoreboard_bottom, vid_conheight * 0.5 + 16), + (havail - h)/2 + ), + havail - h + ); +#endif + + centerprint_num = i; + centerprint_expire = time + cvar("scr_centertime"); +} + +void Sbar_DrawCenterPrint (void) +{ + float i; + vector pos; + string ts; + + if(time > centerprint_expire) + return; + + pos = centerprint_start; + for (i=0; i= n) diff --git a/data/qcsrc/common/util.qc b/data/qcsrc/common/util.qc index cfc2b6c3e..472043f60 100644 --- a/data/qcsrc/common/util.qc +++ b/data/qcsrc/common/util.qc @@ -1357,3 +1357,116 @@ vector AnglesTransform_Divide(vector to_transform, vector from_transform) return AnglesTransform_Multiply(to_transform, AnglesTransform_Invert(from_transform)); } #endif + +float textLengthUpToWidth(string theText, float maxWidth, textLengthUpToWidth_widthFunction_t w) +{ + float ICanHasKallerz; + + // detect color codes support in the width function + ICanHasKallerz = (w("^7") == 0); + + // STOP. + // The following function is SLOW. + // For your safety and for the protection of those around you... + // DO NOT CALL THIS AT HOME. + // No really, don't. + if(w(theText) <= maxWidth) + return strlen(theText); // yeah! + + // binary search for right place to cut string + float ch; + float left, right, middle; // this always works + left = 0; + right = strlen(theText); // this always fails + do + { + middle = floor((left + right) / 2); + if(w(substring(theText, 0, middle)) <= maxWidth) + left = middle; + else + right = middle; + } + while(left < right - 1); + + if(ICanHasKallerz) + { + // NOTE: when color codes are involved, this binary search is, + // mathematically, BROKEN. However, it is obviously guaranteed to + // terminate, as the range still halves each time - but nevertheless, it is + // guaranteed that it finds ONE valid cutoff place (where "left" is in + // range, and "right" is outside). + + // terencehill: the following code detects truncated ^xrgb tags (e.g. ^x or ^x4) + // and decrease left on the basis of the chars detected of the truncated tag + // Even if the ^xrgb tag is not complete/correct, left is decreased + // (sometimes too much but with a correct result) + // it fixes also ^[0-9] + while(left >= 1 && substring(theText, left-1, 1) == "^") + left-=1; + + if (left >= 2 && substring(theText, left-2, 2) == "^x") // ^x/ + left-=2; + else if (left >= 3 && substring(theText, left-3, 2) == "^x") + { + ch = str2chr(theText, left-1); + if( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') ) // ^xr/ + left-=3; + } + else if (left >= 4 && substring(theText, left-4, 2) == "^x") + { + ch = str2chr(theText, left-2); + if ( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') ) + { + ch = str2chr(theText, left-1); + if ( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') ) // ^xrg/ + left-=4; + } + } + } + + return left; +} + +string getWrappedLine(float w, textLengthUpToWidth_widthFunction_t tw) +{ + float cantake; + float take; + string s; + + s = getWrappedLine_remaining; + + cantake = textLengthUpToWidth(s, w, tw); + if(cantake > 0 && cantake < strlen(s)) + { + take = cantake - 1; + while(take > 0 && substring(s, take, 1) != " ") + --take; + if(take == 0) + { + getWrappedLine_remaining = substring(s, cantake, strlen(s) - cantake); + if(getWrappedLine_remaining == "") + getWrappedLine_remaining = string_null; + return substring(s, 0, cantake); + } + else + { + getWrappedLine_remaining = substring(s, take + 1, strlen(s) - take); + if(getWrappedLine_remaining == "") + getWrappedLine_remaining = string_null; + return substring(s, 0, take); + } + } + else + { + getWrappedLine_remaining = string_null; + return s; + } +} + +string textShortenToWidth(string theText, float maxWidth, textLengthUpToWidth_widthFunction_t tw) +{ + if(tw(theText) <= maxWidth) + return theText; + else + return strcat(substring(theText, 0, textLengthUpToWidth(theText, maxWidth - tw("..."), tw)), "..."); +} diff --git a/data/qcsrc/common/util.qh b/data/qcsrc/common/util.qh index 384db5868..77d372fda 100644 --- a/data/qcsrc/common/util.qh +++ b/data/qcsrc/common/util.qh @@ -143,3 +143,10 @@ vector AnglesTransform_Invert(vector transform); vector AnglesTransform_TurnDirection(vector transform); vector AnglesTransform_Divide(vector to_transform, vector from_transform); #endif + +typedef float(string s) textLengthUpToWidth_widthFunction_t; +float textLengthUpToWidth(string theText, float maxWidth, textLengthUpToWidth_widthFunction_t tw); +string textShortenToWidth(string theText, float maxWidth, textLengthUpToWidth_widthFunction_t tw); + +string getWrappedLine_remaining; +string getWrappedLine(float w, textLengthUpToWidth_widthFunction_t tw); diff --git a/data/qcsrc/menu/draw.qc b/data/qcsrc/menu/draw.qc index ac53c0e0e..d0a24749e 100644 --- a/data/qcsrc/menu/draw.qc +++ b/data/qcsrc/menu/draw.qc @@ -284,62 +284,20 @@ string draw_TextShortenToWidth(string theText, float maxWidth, float ICanHasKall return strcat(substring(theText, 0, draw_TextLengthUpToWidth(theText, maxWidth - draw_TextWidth("...", ICanHasKallerz), ICanHasKallerz)), "..."); } -float draw_TextLengthUpToWidth(string theText, float maxWidth, float ICanHasKallerz) +float draw_TextWidth_WithColors(string s) { - // STOP. - // The following function is SLOW. - // For your safety and for the protection of those around you... - // DO NOT CALL THIS AT HOME. - // No really, don't. - if(draw_TextWidth(theText, ICanHasKallerz) <= maxWidth) - return strlen(theText); // yeah! + return draw_TextWidth(s, TRUE); +} - // binary search for right place to cut string - float ch; - float left, right, middle; // this always works - left = 0; - right = strlen(theText); // this always fails - do - { - middle = floor((left + right) / 2); - if(draw_TextWidth(substring(theText, 0, middle), ICanHasKallerz) <= maxWidth) - left = middle; - else - right = middle; - } - while(left < right - 1); +float draw_TextWidth_WithoutColors(string s) +{ + return draw_TextWidth(s, FALSE); +} - // NOTE: when color codes are involved, this binary search is, - // mathematically, BROKEN. However, it is obviously guaranteed to - // terminate, as the range still halves each time - but nevertheless, it is - // guaranteed that it finds ONE valid cutoff place (where "left" is in - // range, and "right" is outside). - - // terencehill: the following code detects truncated ^xrgb tags (e.g. ^x or ^x4) - // and decrease left on the basis of the chars detected of the truncated tag - // Even if the ^xrgb tag is not complete/correct, left is decreased - // (sometimes too much but with a correct result) - // it fixes also ^[0-9] - if (left >= 1 && substring(theText, left-1, 1) == "^") // * it doesn't consider one or more ^ before the current ^ - left-=1; - else if (left >= 2 && substring(theText, left-2, 2) == "^x") // ^x/ - left-=2; - else if (left >= 3 && substring(theText, left-3, 2) == "^x") - { - ch = str2chr(theText, left-1); - if( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') ) // ^xr/ - left-=3; - } - else if (left >= 4 && substring(theText, left-4, 2) == "^x") - { - ch = str2chr(theText, left-2); - if ( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') ) - { - ch = str2chr(theText, left-1); - if ( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') ) // ^xrg/ - left-=4; - } - } - - return left; +float draw_TextLengthUpToWidth(string theText, float maxWidth, float allowColorCodes) +{ + if(allowColorCodes) + return textLengthUpToWidth(theText, maxWidth, draw_TextWidth_WithColors); + else + return textLengthUpToWidth(theText, maxWidth, draw_TextWidth_WithoutColors); } diff --git a/data/qcsrc/menu/draw.qh b/data/qcsrc/menu/draw.qh index fc353f0cb..6ee212706 100644 --- a/data/qcsrc/menu/draw.qh +++ b/data/qcsrc/menu/draw.qh @@ -31,3 +31,6 @@ vector globalToBoxSize(vector v, vector scale); float draw_NeedResizeNotify; string draw_currentSkin; + +float draw_TextWidth_WithColors(string s); +float draw_TextWidth_WithoutColors(string s); diff --git a/data/qcsrc/menu/item/label.c b/data/qcsrc/menu/item/label.c index 0302f4e20..be4bb2a7e 100644 --- a/data/qcsrc/menu/item/label.c +++ b/data/qcsrc/menu/item/label.c @@ -78,7 +78,7 @@ void drawLabel(entity me) o = me.realOrigin; while(getWrappedLine_remaining) { - t = getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight) / me.realFontSize_x); + t = getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight) / me.realFontSize_x, draw_TextWidth_WithoutColors); draw_Text(o, t, me.realFontSize, me.colorL, me.alpha, 0); o_y += me.realFontSize_y; } diff --git a/data/qcsrc/menu/nexuiz/campaign.c b/data/qcsrc/menu/nexuiz/campaign.c index 90e9da4ca..a11c9745a 100644 --- a/data/qcsrc/menu/nexuiz/campaign.c +++ b/data/qcsrc/menu/nexuiz/campaign.c @@ -74,7 +74,7 @@ void rewrapCampaign(float w, float l0, float emptyheight) getWrappedLine_remaining = s; while(getWrappedLine_remaining) { - s = getWrappedLine(w); + s = getWrappedLine(w, draw_TextWidth_WithoutColors); if(--l < 0) goto toolong; r = strcat(r, s, "\n"); } diff --git a/data/qcsrc/menu/nexuiz/util.qc b/data/qcsrc/menu/nexuiz/util.qc index 35968f931..fdf62799f 100644 --- a/data/qcsrc/menu/nexuiz/util.qc +++ b/data/qcsrc/menu/nexuiz/util.qc @@ -312,40 +312,3 @@ void preMenuDraw() campaign_won_previous = cvar(strcat("g_campaign", campaign_name, "_won")); } } - -string getWrappedLine_remaining; -string getWrappedLine(float w) -{ - float cantake; - float take; - string s; - - s = getWrappedLine_remaining; - - cantake = draw_TextLengthUpToWidth(s, w, 0); - if(cantake > 0 && cantake < strlen(s)) - { - take = cantake - 1; - while(take > 0 && substring(s, take, 1) != " ") - --take; - if(take == 0) - { - getWrappedLine_remaining = substring(s, cantake, strlen(s) - cantake); - if(getWrappedLine_remaining == "") - getWrappedLine_remaining = string_null; - return substring(s, 0, cantake); - } - else - { - getWrappedLine_remaining = substring(s, take + 1, strlen(s) - take); - if(getWrappedLine_remaining == "") - getWrappedLine_remaining = string_null; - return substring(s, 0, take); - } - } - else - { - getWrappedLine_remaining = string_null; - return s; - } -} diff --git a/data/qcsrc/menu/nexuiz/util.qh b/data/qcsrc/menu/nexuiz/util.qh index d2be97aa5..f5d1f75ce 100644 --- a/data/qcsrc/menu/nexuiz/util.qh +++ b/data/qcsrc/menu/nexuiz/util.qh @@ -9,6 +9,3 @@ void setDependentAND(entity e, string theCvarName, float theCvarMin, float theCv void setDependentOR(entity e, string theCvarName, float theCvarMin, float theCvarMax, string theCvar2Name, float theCvar2Min, float theCvar2Max); void setDependentAND3(entity e, string theCvarName, float theCvarMin, float theCvarMax, string theCvar2Name, float theCvar2Min, float theCvar2Max, string theCvar3Name, float theCvar3Min, float theCvar3Max); void setDependentStringNotEqual(entity e, string theCvarName, string theCvarValue); - -string getWrappedLine_remaining; -string getWrappedLine(float w); diff --git a/data/qcsrc/server/campaign.qc b/data/qcsrc/server/campaign.qc index d4d61327d..c1d0d4ca7 100644 --- a/data/qcsrc/server/campaign.qc +++ b/data/qcsrc/server/campaign.qc @@ -39,7 +39,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", wordwrap(campaign_longdesc[0], 50), "\n\n^1press jump to enter the game")); + 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")); strunzone(title); } diff --git a/data/qcsrc/server/cl_player.qc b/data/qcsrc/server/cl_player.qc index 495d6756f..7cb2431ba 100644 --- a/data/qcsrc/server/cl_player.qc +++ b/data/qcsrc/server/cl_player.qc @@ -742,11 +742,13 @@ void Say(entity source, float teamsay, string msgin, float floodcontrol) namestr = source.netname; if(teamsay) { - msgstr = strzone(strcat("\{1}\{13}", colorstr, "(^3", namestr, colorstr, ") ^7", msgin, "\n")); - cmsgstr = strcat(colorstr, "(^3", namestr, colorstr, ")\n^7", wordwrap(msgin, 50)); + msgstr = strcat("\{1}\{13}", colorstr, "(^3", namestr, colorstr, ") ^7", msgin); + cmsgstr = strcat(colorstr, "(^3", namestr, colorstr, ")\n^7", msgin); } else - msgstr = strzone(strcat("\{1}", namestr, "^7: ", msgin, "\n")); + msgstr = strcat("\{1}", namestr, "^7: ", msgin); + + msgstr = strcat(strreplace("\n", " ", msgstr), "\n"); // newlines only are good for centerprint // FLOOD CONTROL flood = 0; @@ -830,8 +832,6 @@ void Say(entity source, float teamsay, string msgin, float floodcontrol) else bprint(msgstr); } - - strunzone(msgstr); } float GetVoiceMessageVoiceType(string type) diff --git a/data/qcsrc/server/miscfunctions.qc b/data/qcsrc/server/miscfunctions.qc index 26f5d367a..96d6f8796 100644 --- a/data/qcsrc/server/miscfunctions.qc +++ b/data/qcsrc/server/miscfunctions.qc @@ -395,12 +395,10 @@ string NearestLocation(vector p) string formatmessage(string msg) { - float p; + float p, p1, p2; float n; - string msg_save; string escape; string replacement; - msg_save = strzone(msg); p = 0; n = 7; while(1) @@ -408,13 +406,25 @@ string formatmessage(string msg) if(n < 1) break; // too many replacements n = n - 1; - p = strstr(msg_save, "%", p); // NOTE: this destroys msg as it's a tempstring! + p1 = strstr(msg, "%", p); // NOTE: this destroys msg as it's a tempstring! + p2 = strstr(msg, "\\", p); // NOTE: this destroys msg as it's a tempstring! + + if(p1 < 0) + p1 = p2; + if(p2 < 0) + p2 = p1; + p = min(p1, p2); + if(p < 0) break; - replacement = substring(msg_save, p, 2); - escape = substring(msg_save, p + 1, 1); + replacement = substring(msg, p, 2); + escape = substring(msg, p + 1, 1); if(escape == "%") replacement = "%"; + else if(escape == "\\") + replacement = "\\"; + else if(escape == "n") + replacement = "\n"; else if(escape == "a") replacement = ftos(floor(self.armorvalue)); else if(escape == "h") @@ -456,14 +466,9 @@ string formatmessage(string msg) else replacement = "(nobody)"; } - msg = strcat(substring(msg_save, 0, p), replacement); - msg = strcat(msg, substring(msg_save, p+2, strlen(msg_save) - (p+2))); - strunzone(msg_save); - msg_save = strzone(msg); - p = p + 2; - } - msg = strcat(msg_save, ""); - strunzone(msg_save); + msg = strcat(substring(msg, 0, p), replacement, substring(msg, p+2, strlen(msg) - (p+2))); + p = p + strlen(replacement); + } return msg; } diff --git a/data/qcsrc/server/teamplay.qc b/data/qcsrc/server/teamplay.qc index 873e93f20..81328db3b 100644 --- a/data/qcsrc/server/teamplay.qc +++ b/data/qcsrc/server/teamplay.qc @@ -1,6 +1,4 @@ -string cache_motd; string cache_mutatormsg; -string cache_lastmotd; string cache_lastmutatormsg; // client counts for each team @@ -330,9 +328,7 @@ void InitGameplayMode() cvar_set("gamecfg", ftos(game)); cache_mutatormsg = strzone(""); - cache_motd = strzone(""); cache_lastmutatormsg = strzone(""); - cache_lastmotd = strzone(""); // enforce the server's universal frag/time limits if(!cvar("g_campaign")) @@ -369,7 +365,7 @@ string GetClientVersionMessage() { void PrintWelcomeMessage(entity pl) { - string s, mutator, modifications; + string s, mutator, modifications, motd; /*if(self.welcomemessage_time > time) return; @@ -475,25 +471,16 @@ void PrintWelcomeMessage(entity pl) if(cache_mutatormsg) strunzone(cache_mutatormsg); cache_lastmutatormsg = strzone(cvar_string("g_mutatormsg")); - cache_mutatormsg = strzone(wordwrap(cache_lastmutatormsg, 50)); + cache_mutatormsg = strzone(cache_lastmutatormsg); } if (cache_mutatormsg != "") { s = strcat(s, "\n\n^8special gameplay tips: ^7", cache_mutatormsg); } - if(cache_lastmotd != cvar_string("sv_motd")) - { - if(cache_lastmotd) - strunzone(cache_lastmotd); - if(cache_motd) - strunzone(cache_motd); - cache_lastmotd = strzone(cvar_string("sv_motd")); - cache_motd = strzone(wordwrap(cache_lastmotd, 50)); - } - - if (cache_motd != "") { - s = strcat(s, "\n\n^8MOTD: ^7", cache_motd); + motd = cvar_string("sv_motd"); + if (motd != "") { + s = strcat(s, "\n\n^8MOTD: ^7", strreplace("\\n", "\n", motd)); } s = strcat(s, "\n"); -- 2.39.2