X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Futil.qc;h=8ef6b2019f07c4a08d5467897214d5717ce03c56;hp=0b1b96880dc93985a6711c17a80183a795de0495;hb=HEAD;hpb=98c2e6191191bf34955f14572b3db8ebcb3aec93 diff --git a/qcsrc/common/util.qc b/qcsrc/common/util.qc index 0b1b96880d..ca120d2953 100644 --- a/qcsrc/common/util.qc +++ b/qcsrc/common/util.qc @@ -239,7 +239,7 @@ string build_mutator_list(string s) n = tokenizebyseparator(s, ", "); } string s2 = ""; - for (string arg = ""; i < n; i++) + for (string arg = ""; i < n; ++i) { if (i >= 0) arg = argv(i); // cond is the condition for showing the mutator enabled in the menu @@ -372,7 +372,7 @@ void depthfirst(entity start, .entity up, .entity downleft, .entity right, void( } #ifdef GAMEQC -string ScoreString(int pFlags, float pValue) +string ScoreString(int pFlags, float pValue, int rounds_played) { string valstr; float l; @@ -384,7 +384,9 @@ string ScoreString(int pFlags, float pValue) else if(pFlags & SFL_RANK) valstr = (pValue < 256 ? count_ordinal(pValue) : _("N/A")); else if(pFlags & SFL_TIME) - valstr = TIME_ENCODED_TOSTRING(pValue); + valstr = TIME_ENCODED_TOSTRING(pValue, true); + else if (rounds_played) + valstr = sprintf("%.1f", pValue / rounds_played); else valstr = ftos(pValue); @@ -442,7 +444,7 @@ vector decompressShortVector(int data) float q = (data & 0x0F80) / 0x80; int len = (data & 0x007F); - //print("\ndecompress: p ", ftos(p)); print("q ", ftos(q)); print("len ", ftos(len), "\n"); + //print("\ndecompress: p:", ftos(p)); print(" q:", ftos(q)); print(" len:", ftos(len), "\n"); if(p == 0) { @@ -455,7 +457,7 @@ vector decompressShortVector(int data) } else { - q = .19634954084936207740 * q; + q = .19634954084936207740 * q; p = .19634954084936207740 * p - 1.57079632679489661922; out.x = cos(q) * cos(p); out.y = sin(q) * cos(p); @@ -491,10 +493,10 @@ float compressShortVector(vector vec) y = 30; } else - y = floor(0.5 + ang.y * 32 / 360) & 31; // 0..360 to 0..32 + y = floor(0.5 + ang.y * 32 / 360) & 31; // 0..360 to 0..32 len = invertLengthLog(vlen(vec)); - //print("compressed: p ", ftos(p)); print("y ", ftos(y)); print("len ", ftos(len), "\n"); + //print("compressed: p:", ftos(p)); print(" y:", ftos(y)); print(" len:", ftos(len), "\n"); return (p * 0x1000) + (y * 0x80) + len; } @@ -870,14 +872,14 @@ float textLengthUpToWidth(string theText, float maxWidth, vector theSize, textLe return left; } -float textLengthUpToLength(string theText, float maxWidth, textLengthUpToLength_lenFunction_t w) +float textLengthUpToLength(string theText, int maxLength, textLengthUpToLength_lenFunction_t w) { // 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) + if(w(theText) <= maxLength) return strlen(theText); // yeah! bool colors = (w("^7") == 0); @@ -896,7 +898,7 @@ float textLengthUpToLength(string theText, float maxWidth, textLengthUpToLength_ ofs = (!res.x) ? 0 : res.x - res.y; } - if(w(substring(theText, 0, middle + ofs)) <= maxWidth) + if(w(substring(theText, 0, middle + ofs)) <= maxLength) left = middle + ofs; else right = middle; @@ -941,17 +943,17 @@ string find_last_color_code(string s) return ""; } -string getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunction_t tw) +string getWrappedLine(float maxWidth, vector theFontSize, textLengthUpToWidth_widthFunction_t tw) { string s = getWrappedLine_remaining; - if(w <= 0) + if(maxWidth <= 0) { getWrappedLine_remaining = string_null; return s; // the line has no size ANYWAY, nothing would be displayed. } - int take_until = textLengthUpToWidth(s, w, theFontSize, tw); + int take_until = textLengthUpToWidth(s, maxWidth, theFontSize, tw); if(take_until > 0 && take_until < strlen(s)) { int last_word = take_until - 1; @@ -979,17 +981,17 @@ string getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunc } } -string getWrappedLineLen(float w, textLengthUpToLength_lenFunction_t tw) +string getWrappedLineLen(int maxLength, textLengthUpToLength_lenFunction_t tw) { string s = getWrappedLine_remaining; - if(w <= 0) + if(maxLength <= 0) { getWrappedLine_remaining = string_null; return s; // the line has no size ANYWAY, nothing would be displayed. } - int take_until = textLengthUpToLength(s, w, tw); + int take_until = textLengthUpToLength(s, maxLength, tw); if(take_until > 0 && take_until < strlen(s)) { int last_word = take_until - 1; @@ -1182,35 +1184,56 @@ vector get_shotvelocity(vector myvel, vector mydir, float spd, float newton_styl return myvel + spd * mydir; } +// compresses the shot origin offset vector to an int with the following format: +// xxxxxxxx SSyyyyyy SUzzzzzz +// 32109876 54321098 76543210 +// 1st byte: x component (it uses all 8 bits) +// 2nd byte: y component in the last 6 bits and the signs of the x and y components +// 3rd byte: z component in the last 6 bits and the sign of the z component (the 2nd bit is unused) +// all values are doubled on compression and halved on decompression +// so the precision for all components is 0.5 +// values are bound to the following ranges: +// x: -127.5 +127.5 +// y: -31.5 +31.5 +// z: -31.5 +31.5 float compressShotOrigin(vector v) { - float rx = rint(v.x * 2); - float ry = rint(v.y * 4) + 128; - float rz = rint(v.z * 4) + 128; - if(rx > 255 || rx < 0) + int rx_neg = (v.x < 0) ? 1 : 0; + int ry_neg = (v.y < 0) ? 1 : 0; + int rz_neg = (v.z < 0) ? 1 : 0; + int rx = rint(fabs(v.x) * 2); + int ry = rint(fabs(v.y) * 2); + int rz = rint(fabs(v.z) * 2); + if(rx > 255) // 128 * 2 - 1 { LOG_DEBUG("shot origin ", vtos(v), " x out of bounds\n"); rx = bound(0, rx, 255); } - if(ry > 255 || ry < 0) + if(ry > 63) // 32 * 2 - 1 { LOG_DEBUG("shot origin ", vtos(v), " y out of bounds\n"); - ry = bound(0, ry, 255); + ry = bound(0, ry, 63); } - if(rz > 255 || rz < 0) + if(rz > 63) // 32 * 2 - 1 { LOG_DEBUG("shot origin ", vtos(v), " z out of bounds\n"); - rz = bound(0, rz, 255); + rz = bound(0, rz, 63); } + ry |= ry_neg * BIT(6) + rx_neg * BIT(7); + rz |= rz_neg * BIT(6); // BIT(7) unused return rx * 0x10000 + ry * 0x100 + rz; } vector decompressShotOrigin(int f) { vector v; - v.x = ((f & 0xFF0000) / 0x10000) / 2; - v.y = ((f & 0xFF00) / 0x100 - 128) / 4; - v.z = ((f & 0xFF) - 128) / 4; - return v; + v.x = f >> 16; + v.y = (f & 0xFF00) >> 8; + v.z = f & 0xFF; + // remove sign bits and apply sign + if (v.y & BIT(7)) { v.y &= ~BIT(7); v.x *= -1; } + if (v.y & BIT(6)) { v.y &= ~BIT(6); v.y *= -1; } + if (v.z & BIT(6)) { v.z &= ~BIT(6); v.z *= -1; } + return v / 2; } #ifdef GAMEQC