Lib: re-home functions from common/util
authorTimePath <andrew.hardaker1995@gmail.com>
Thu, 8 Oct 2015 01:37:22 +0000 (12:37 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Thu, 8 Oct 2015 01:37:22 +0000 (12:37 +1100)
15 files changed:
qcsrc/common/util-pre.qh
qcsrc/common/util.qc
qcsrc/common/util.qh
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/lib/_all.inc
qcsrc/lib/bits.qh [new file with mode: 0644]
qcsrc/lib/math.qh
qcsrc/lib/net.qh
qcsrc/lib/prandom.qc [deleted file]
qcsrc/lib/prandom.qh [deleted file]
qcsrc/lib/random.qc [new file with mode: 0644]
qcsrc/lib/random.qh [new file with mode: 0644]
qcsrc/lib/string.qh
qcsrc/lib/vector.qh
qcsrc/server/g_world.qc

index ad9be12..dfb4071 100644 (file)
 #define GET(name) name##get
 #define GETTER(type, name) type GET(name)() { return name; }
 
-#define BIT(n) (1 << (n))
-#ifndef BRANCHLESS_BITSET
-    #define BITSET(var, mask, flag) (flag ? (var) | (mask) : (var) &~ (mask))
-#else
-    #define BITSET(var, mask, flag) ((var) ^ (-(flag) ^ (var)) & (mask))
-#endif
-
 #endif
index e93fd6a..c304ed8 100644 (file)
@@ -72,37 +72,6 @@ string draw_UseSkinFor(string pic)
 }
 #endif
 
-string unescape(string in)
-{
-       float i, len;
-       string str, s;
-
-       // but it doesn't seem to be necessary in my tests at least
-       in = strzone(in);
-
-       len = strlen(in);
-       str = "";
-       for(i = 0; i < len; ++i)
-       {
-               s = substring(in, i, 1);
-               if(s == "\\")
-               {
-                       s = substring(in, i+1, 1);
-                       if(s == "n")
-                               str = strcat(str, "\n");
-                       else if(s == "\\")
-                               str = strcat(str, "\\");
-                       else
-                               str = strcat(str, substring(in, i, 2));
-                       ++i;
-               } else
-                       str = strcat(str, s);
-       }
-
-       strunzone(in);
-       return str;
-}
-
 void wordwrap_cb(string s, float l, void(string) callback)
 {
        string c;
@@ -168,17 +137,6 @@ void wordwrap_cb(string s, float l, void(string) callback)
        strunzone(s);
 }
 
-float dist_point_line(vector p, vector l0, vector ldir)
-{
-       ldir = normalize(ldir);
-
-       // remove the component in line direction
-       p = p - (p * ldir) * ldir;
-
-       // vlen of the remaining vector
-       return vlen(p);
-}
-
 void depthfirst(entity start, .entity up, .entity downleft, .entity right, void(entity, entity) funcPre, void(entity, entity) funcPost, entity pass)
 {
        entity e;
@@ -208,13 +166,6 @@ void depthfirst(entity start, .entity up, .entity downleft, .entity right, void(
        }
 }
 
-float median(float a, float b, float c)
-{
-       if(a < c)
-               return bound(a, b, c);
-       return bound(c, b, a);
-}
-
 // converts a number to a string with the indicated number of decimals
 // works for up to 10 decimals!
 string ftos_decimals(float number, float decimals)
@@ -226,9 +177,9 @@ string ftos_decimals(float number, float decimals)
        return sprintf("%.*f", decimals, number);
 }
 
-vector colormapPaletteColor(float c, float isPants)
+vector colormapPaletteColor(float c, bool isPants)
 {
-       switch(c)
+       switch (c)
        {
                case  0: return '1.000000 1.000000 1.000000';
                case  1: return '1.000000 0.333333 0.000000';
@@ -246,7 +197,7 @@ vector colormapPaletteColor(float c, float isPants)
                case 13: return '0.000000 0.333333 1.000000';
                case 14: return '1.000000 0.666667 0.000000';
                case 15:
-                       if(isPants)
+                       if (isPants)
                                return
                                          '1 0 0' * (0.502 + 0.498 * sin(time / 2.7182818285 + 0.0000000000))
                                        + '0 1 0' * (0.502 + 0.498 * sin(time / 2.7182818285 + 2.0943951024))
@@ -260,17 +211,6 @@ vector colormapPaletteColor(float c, float isPants)
        }
 }
 
-// unzone the string, and return it as tempstring. Safe to be called on string_null
-string fstrunzone(string s)
-{
-       string sc;
-       if (!s)
-               return s;
-       sc = strcat(s, "");
-       strunzone(s);
-       return sc;
-}
-
 // Databases (hash tables)
 const float DB_BUCKETS = 8192;
 void db_save(float db, string pFilename)
@@ -932,103 +872,6 @@ float cvar_settemp_restore()
        return i;
 }
 
-float almost_equals(float a, float b)
-{
-       float eps;
-       eps = (max(a, -a) + max(b, -b)) * 0.001;
-       if(a - b < eps && b - a < eps)
-               return true;
-       return false;
-}
-
-float almost_in_bounds(float a, float b, float c)
-{
-       float eps;
-       eps = (max(a, -a) + max(c, -c)) * 0.001;
-       if(a > c)
-               eps = -eps;
-       return b == median(a - eps, b, c + eps);
-}
-
-float power2of(float e)
-{
-       return pow(2, e);
-}
-float log2of(float x)
-{
-       // NOTE: generated code
-       if(x > 2048)
-               if(x > 131072)
-                       if(x > 1048576)
-                               if(x > 4194304)
-                                       return 23;
-                               else
-                                       if(x > 2097152)
-                                               return 22;
-                                       else
-                                               return 21;
-                       else
-                               if(x > 524288)
-                                       return 20;
-                               else
-                                       if(x > 262144)
-                                               return 19;
-                                       else
-                                               return 18;
-               else
-                       if(x > 16384)
-                               if(x > 65536)
-                                       return 17;
-                               else
-                                       if(x > 32768)
-                                               return 16;
-                                       else
-                                               return 15;
-                       else
-                               if(x > 8192)
-                                       return 14;
-                               else
-                                       if(x > 4096)
-                                               return 13;
-                                       else
-                                               return 12;
-       else
-               if(x > 32)
-                       if(x > 256)
-                               if(x > 1024)
-                                       return 11;
-                               else
-                                       if(x > 512)
-                                               return 10;
-                                       else
-                                               return 9;
-                       else
-                               if(x > 128)
-                                       return 8;
-                               else
-                                       if(x > 64)
-                                               return 7;
-                                       else
-                                               return 6;
-               else
-                       if(x > 4)
-                               if(x > 16)
-                                       return 5;
-                               else
-                                       if(x > 8)
-                                               return 4;
-                                       else
-                                               return 3;
-                       else
-                               if(x > 2)
-                                       return 2;
-                               else
-                                       if(x > 1)
-                                               return 1;
-                                       else
-                                               return 0;
-}
-
 float rgb_mi_ma_to_hue(vector rgb, float mi, float ma)
 {
        if(mi == ma)
@@ -1173,15 +1016,6 @@ string rgb_to_hexcolor(vector rgb)
                );
 }
 
-// requires that m2>m1 in all coordinates, and that m4>m3
-float boxesoverlap(vector m1, vector m2, vector m3, vector m4) {return m2_x >= m3_x && m1_x <= m4_x && m2_y >= m3_y && m1_y <= m4_y && m2_z >= m3_z && m1_z <= m4_z;}
-
-// requires the same, but is a stronger condition
-float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) {return smins.x >= bmins.x && smaxs.x <= bmaxs.x && smins.y >= bmins.y && smaxs.y <= bmaxs.y && smins.z >= bmins.z && smaxs.z <= bmaxs.z;}
-
-#ifndef MENUQC
-#endif
-
 float textLengthUpToWidth(string theText, float maxWidth, vector theSize, textLengthUpToWidth_widthFunction_t w)
 {
        // STOP.
@@ -1500,47 +1334,6 @@ float isGametypeInFilter(float gt, float tp, float ts, string pattern)
        return 1;
 }
 
-string substring_range(string s, float b, float e)
-{
-       return substring(s, b, e - b);
-}
-
-string swapwords(string str, float i, float j)
-{
-       float n;
-       string s1, s2, s3, s4, s5;
-       float si, ei, sj, ej, s0, en;
-       n = tokenizebyseparator(str, " "); // must match g_maplist processing in ShuffleMaplist and "shuffle"
-       si = argv_start_index(i);
-       sj = argv_start_index(j);
-       ei = argv_end_index(i);
-       ej = argv_end_index(j);
-       s0 = argv_start_index(0);
-       en = argv_end_index(n-1);
-       s1 = substring_range(str, s0, si);
-       s2 = substring_range(str, si, ei);
-       s3 = substring_range(str, ei, sj);
-       s4 = substring_range(str, sj, ej);
-       s5 = substring_range(str, ej, en);
-       return strcat(s1, s4, s3, s2, s5);
-}
-
-string _shufflewords_str;
-void _shufflewords_swapfunc(float i, float j, entity pass)
-{
-       _shufflewords_str = swapwords(_shufflewords_str, i, j);
-}
-string shufflewords(string str)
-{
-       float n;
-       _shufflewords_str = str;
-       n = tokenizebyseparator(str, " ");
-       shuffle(n, _shufflewords_swapfunc, world);
-       str = _shufflewords_str;
-       _shufflewords_str = string_null;
-       return str;
-}
-
 vector solve_quadratic(float a, float b, float c) // ax^2 + bx + c = 0
 {
        vector v;
@@ -1730,37 +1523,6 @@ vector decompressShotOrigin(int f)
        return v;
 }
 
-
-void RandomSelection_Init()
-{
-       RandomSelection_totalweight = 0;
-       RandomSelection_chosen_ent = world;
-       RandomSelection_chosen_float = 0;
-       RandomSelection_chosen_string = string_null;
-       RandomSelection_best_priority = -1;
-}
-void RandomSelection_Add(entity e, float f, string s, float weight, float priority)
-{
-       if(priority > RandomSelection_best_priority)
-       {
-               RandomSelection_best_priority = priority;
-               RandomSelection_chosen_ent = e;
-               RandomSelection_chosen_float = f;
-               RandomSelection_chosen_string = s;
-               RandomSelection_totalweight = weight;
-       }
-       else if(priority == RandomSelection_best_priority)
-       {
-               RandomSelection_totalweight += weight;
-               if(random() * RandomSelection_totalweight <= weight)
-               {
-                       RandomSelection_chosen_ent = e;
-                       RandomSelection_chosen_float = f;
-                       RandomSelection_chosen_string = s;
-               }
-       }
-}
-
 #ifndef MENUQC
 vector healtharmor_maxdamage(float h, float a, float armorblock, int deathtype)
 {
@@ -1810,63 +1572,6 @@ string getcurrentmod()
                return argv(n - 1);
 }
 
-#ifndef MENUQC
-#ifdef CSQC
-int ReadInt24_t()
-{
-       int v = ReadShort() * 256; // note: this is signed
-       v += ReadByte(); // note: this is unsigned
-       return v;
-}
-vector ReadInt48_t()
-{
-       vector v;
-       v.x = ReadInt24_t();
-       v.y = ReadInt24_t();
-       v.z = 0;
-       return v;
-}
-vector ReadInt72_t()
-{
-       vector v;
-       v.x = ReadInt24_t();
-       v.y = ReadInt24_t();
-       v.z = ReadInt24_t();
-       return v;
-}
-#else
-void WriteInt24_t(float dst, float val)
-{
-       float v;
-       WriteShort(dst, (v = floor(val / 256)));
-       WriteByte(dst, val - v * 256); // 0..255
-}
-void WriteInt48_t(float dst, vector val)
-{
-       WriteInt24_t(dst, val.x);
-       WriteInt24_t(dst, val.y);
-}
-void WriteInt72_t(float dst, vector val)
-{
-       WriteInt24_t(dst, val.x);
-       WriteInt24_t(dst, val.y);
-       WriteInt24_t(dst, val.z);
-}
-#endif
-#endif
-
-float float2range11(float f)
-{
-       // continuous function mapping all reals into -1..1
-       return f / (fabs(f) + 1);
-}
-
-float float2range01(float f)
-{
-       // continuous function mapping all reals into 0..1
-       return 0.5 + 0.5 * float2range11(f);
-}
-
 // from the GNU Scientific Library
 float gsl_ran_gaussian_lastvalue;
 float gsl_ran_gaussian_lastvalue_set;
@@ -1888,22 +1593,6 @@ float gsl_ran_gaussian(float sigma)
        }
 }
 
-string car(string s)
-{
-       float o;
-       o = strstrofs(s, " ", 0);
-       if(o < 0)
-               return s;
-       return substring(s, 0, o);
-}
-string cdr(string s)
-{
-       float o;
-       o = strstrofs(s, " ", 0);
-       if(o < 0)
-               return string_null;
-       return substring(s, o + 1, strlen(s) - (o + 1));
-}
 float matchacl(string acl, string str)
 {
        string t, s;
@@ -1937,14 +1626,6 @@ float matchacl(string acl, string str)
        }
        return r;
 }
-float startsWith(string haystack, string needle)
-{
-       return substring(haystack, 0, strlen(needle)) == needle;
-}
-float startsWithNocase(string haystack, string needle)
-{
-       return strcasecmp(substring(haystack, 0, strlen(needle)), needle) == 0;
-}
 
 string get_model_datafilename(string m, float sk, string fil)
 {
@@ -2069,28 +1750,6 @@ float get_model_parameters(string m, float sk)
        return 1;
 }
 
-vector vec2(vector v)
-{
-       v.z = 0;
-       return v;
-}
-
-#ifndef MENUQC
-vector NearestPointOnBox(entity box, vector org)
-{
-       vector m1, m2, nearest;
-
-       m1 = box.mins + box.origin;
-       m2 = box.maxs + box.origin;
-
-       nearest.x = bound(m1_x, org.x, m2_x);
-       nearest.y = bound(m1_y, org.y, m2_y);
-       nearest.z = bound(m1_z, org.z, m2_z);
-
-       return nearest;
-}
-#endif
-
 float vercmp_recursive(string v1, string v2)
 {
        float dot1, dot2;
@@ -2142,26 +1801,6 @@ float vercmp(string v1, string v2)
        return vercmp_recursive(v1, v2);
 }
 
-float u8_strsize(string s)
-{
-       float l, i, c;
-       l = 0;
-       for(i = 0; ; ++i)
-       {
-               c = str2chr(s, i);
-               if(c <= 0)
-                       break;
-               ++l;
-               if(c >= 0x80)
-                       ++l;
-               if(c >= 0x800)
-                       ++l;
-               if(c >= 0x10000)
-                       ++l;
-       }
-       return l;
-}
-
 // x-encoding (encoding as zero length invisible string)
 const string XENCODE_2  = "xX";
 const string XENCODE_22 = "0123456789abcdefABCDEF";
@@ -2196,16 +1835,6 @@ float xdecode(string s)
        return ((a * 22 + b) * 22 + c) * 22 + d;
 }
 
-int lowestbit(int f)
-{
-       f &= ~(f * 2);
-       f &= ~(f * 4);
-       f &= ~(f * 16);
-       f &= ~(f * 256);
-       f &= ~(f * 65536);
-       return f;
-}
-
 /*
 string strlimitedlen(string input, string truncation, float strip_colors, float limit)
 {
@@ -2322,80 +1951,6 @@ void queue_to_execute_next_frame(string s)
        to_execute_next_frame = strzone(s);
 }
 
-float cubic_speedfunc(float startspeedfactor, float endspeedfactor, float x)
-{
-       return
-               (((     startspeedfactor + endspeedfactor - 2
-               ) * x - 2 * startspeedfactor - endspeedfactor + 3
-               ) * x + startspeedfactor
-               ) * x;
-}
-
-float cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor)
-{
-       if(startspeedfactor < 0 || endspeedfactor < 0)
-               return false;
-
-       /*
-       // if this is the case, the possible zeros of the first derivative are outside
-       // 0..1
-       We can calculate this condition as condition
-       if(se <= 3)
-               return true;
-       */
-
-       // better, see below:
-       if(startspeedfactor <= 3 && endspeedfactor <= 3)
-               return true;
-
-       // if this is the case, the first derivative has no zeros at all
-       float se = startspeedfactor + endspeedfactor;
-       float s_e = startspeedfactor - endspeedfactor;
-       if(3 * (se - 4) * (se - 4) + s_e * s_e <= 12) // an ellipse
-               return true;
-
-       // Now let s <= 3, s <= 3, s+e >= 3 (triangle) then we get se <= 6 (top right corner).
-       // we also get s_e <= 6 - se
-       // 3 * (se - 4)^2 + (6 - se)^2
-       // is quadratic, has value 12 at 3 and 6, and value < 12 in between.
-       // Therefore, above "better" check works!
-
-       return false;
-
-       // known good cases:
-       // (0, [0..3])
-       // (0.5, [0..3.8])
-       // (1, [0..4])
-       // (1.5, [0..3.9])
-       // (2, [0..3.7])
-       // (2.5, [0..3.4])
-       // (3, [0..3])
-       // (3.5, [0.2..2.3])
-       // (4, 1)
-
-       /*
-          On another note:
-          inflection point is always at (2s + e - 3) / (3s + 3e - 6).
-
-          s + e - 2 == 0: no inflection
-
-          s + e > 2:
-          0 < inflection < 1 if:
-          0 < 2s + e - 3 < 3s + 3e - 6
-          2s + e > 3 and 2e + s > 3
-
-          s + e < 2:
-          0 < inflection < 1 if:
-          0 > 2s + e - 3 > 3s + 3e - 6
-          2s + e < 3 and 2e + s < 3
-
-          Therefore: there is an inflection point iff:
-          e outside (3 - s)/2 .. 3 - s*2
-
-          in other words, if (s,e) in triangle (1,1)(0,3)(0,1.5) or in triangle (1,1)(3,0)(1.5,0)
-       */
-}
-
 .float FindConnectedComponent_processing;
 void FindConnectedComponent(entity e, .entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass)
 {
@@ -2438,61 +1993,6 @@ void FindConnectedComponent(entity e, .entity fld, findNextEntityNearFunction_t
                queue_start.FindConnectedComponent_processing = 0;
 }
 
-#ifdef SVQC
-vector combine_to_vector(float x, float y, float z)
-{
-       vector result; result_x = x; result_y = y; result_z = z;
-       return result;
-}
-
-vector get_corner_position(entity box, float corner)
-{
-       switch(corner)
-       {
-               case 1: return combine_to_vector(box.absmin.x, box.absmin.y, box.absmin.z);
-               case 2: return combine_to_vector(box.absmax.x, box.absmin.y, box.absmin.z);
-               case 3: return combine_to_vector(box.absmin.x, box.absmax.y, box.absmin.z);
-               case 4: return combine_to_vector(box.absmin.x, box.absmin.y, box.absmax.z);
-               case 5: return combine_to_vector(box.absmax.x, box.absmax.y, box.absmin.z);
-               case 6: return combine_to_vector(box.absmin.x, box.absmax.y, box.absmax.z);
-               case 7: return combine_to_vector(box.absmax.x, box.absmin.y, box.absmax.z);
-               case 8: return combine_to_vector(box.absmax.x, box.absmax.y, box.absmax.z);
-               default: return '0 0 0';
-       }
-}
-#endif
-
-// color code replace, place inside of sprintf and parse the string
-string CCR(string input)
-{
-       // See the autocvar declarations in util.qh for default values
-
-       // foreground/normal colors
-       input = strreplace("^F1", strcat("^", autocvar_hud_colorset_foreground_1), input);
-       input = strreplace("^F2", strcat("^", autocvar_hud_colorset_foreground_2), input);
-       input = strreplace("^F3", strcat("^", autocvar_hud_colorset_foreground_3), input);
-       input = strreplace("^F4", strcat("^", autocvar_hud_colorset_foreground_4), input);
-
-       // "kill" colors
-       input = strreplace("^K1", strcat("^", autocvar_hud_colorset_kill_1), input);
-       input = strreplace("^K2", strcat("^", autocvar_hud_colorset_kill_2), input);
-       input = strreplace("^K3", strcat("^", autocvar_hud_colorset_kill_3), input);
-
-       // background colors
-       input = strreplace("^BG", strcat("^", autocvar_hud_colorset_background), input);
-       input = strreplace("^N", "^7", input); // "none"-- reset to white...
-       return input;
-}
-
-vector vec3(float x, float y, float z)
-{
-       vector v;
-       v.x = x;
-       v.y = y;
-       v.z = z;
-       return v;
-}
-
 #ifndef MENUQC
 vector animfixfps(entity e, vector a, vector b)
 {
@@ -2668,18 +2168,3 @@ int Mod_Q1BSP_NativeContentsFromSuperContents(int supercontents)
        return CONTENT_EMPTY;
 }
 #endif
-
-vector bezier_quadratic_getpoint(vector a, vector b, vector c, float t)
-{
-       return
-               (c - 2 * b + a) * (t * t) +
-               (b - a) * (2 * t) +
-               a;
-}
-
-vector bezier_quadratic_getderivative(vector a, vector b, vector c, float t)
-{
-       return
-               (c - 2 * b + a) * (2 * t) +
-               (b - a) * 2;
-}
index 4af1680..a2774aa 100644 (file)
@@ -152,14 +152,6 @@ string rankings_reply, ladder_reply, lsmaps_reply, maplist_reply, monsterlist_re
 string records_reply[10];
 #endif
 
-float RandomSelection_totalweight;
-float RandomSelection_best_priority;
-entity RandomSelection_chosen_ent;
-float RandomSelection_chosen_float;
-string RandomSelection_chosen_string;
-void RandomSelection_Init();
-void RandomSelection_Add(entity e, float f, string s, float weight, float priority);
-
 #ifndef MENUQC
 vector healtharmor_maxdamage(float h, float a, float armorblock, int deathtype); // returns vector: maxdamage, armorideal, 1 if fully armored
 vector healtharmor_applydamage(float a, float armorblock, int deathtype, float damage); // returns vector: take, save, 0
@@ -225,8 +217,6 @@ const float XENCODE_LEN = 5;
 string xencode(float f);
 float xdecode(string s);
 
-int lowestbit(float f);
-
 #ifdef CSQC
 entity ReadCSQCEntity();
 #endif
@@ -276,11 +266,6 @@ typedef entity(entity cur, entity near, entity pass) findNextEntityNearFunction_
 typedef float(entity a, entity b, entity pass) isConnectedFunction_t;
 void FindConnectedComponent(entity e, .entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass);
 
-#ifdef SVQC
-vector combine_to_vector(float x, float y, float z);
-vector get_corner_position(entity box, float corner);
-#endif
-
 // expand multiple arguments into one argument by stripping parenthesis
 #define XPD(...) __VA_ARGS__
 
@@ -288,19 +273,6 @@ vector get_corner_position(entity box, float corner);
 #define fprintf(file, ...) fputs(file, sprintf(__VA_ARGS__))
 #define bprintf(...) bprint(sprintf(__VA_ARGS__))
 
-// color code replace, place inside of sprintf and parse the string... defaults described as constants
-// foreground/normal colors
-string autocvar_hud_colorset_foreground_1 = "2"; // F1 - Green  // primary priority (important names, etc)
-string autocvar_hud_colorset_foreground_2 = "3"; // F2 - Yellow // secondary priority (items, locations, numbers, etc)
-string autocvar_hud_colorset_foreground_3 = "4"; // F3 - Blue   // tertiary priority or relatively inconsequential text
-string autocvar_hud_colorset_foreground_4 = "1"; // F4 - Red    // notice/attention grabbing texting
-// "kill" colors
-string autocvar_hud_colorset_kill_1 = "1"; // K1 - Red    // "bad" or "dangerous" text (death messages against you, kill notifications, etc)
-string autocvar_hud_colorset_kill_2 = "3"; // K2 - Yellow // similar to above, but less important... OR, a highlight out of above message type
-string autocvar_hud_colorset_kill_3 = "4"; // K3 - Blue   // "good" or "beneficial" text (you fragging someone, etc)
-// background color
-string autocvar_hud_colorset_background = "7"; // BG - White // neutral/unimportant text
-
 string CCR(string input);
 
 #ifndef MENUQC
index 4965ba6..cc4daf0 100644 (file)
@@ -439,7 +439,7 @@ void W_Shockwave_Attack(void)
                                        );
 
                                // figure out the direction of force
-                               vel = normalize(combine_to_vector(head.velocity.x, head.velocity.y, 0));
+                               vel = normalize(vec3(head.velocity.x, head.velocity.y, 0));
                                vel *=
                                        (
                                                bound(0, (vlen(vel) / autocvar_sv_maxspeed), 1)
index 7dc6074..c00c5a1 100644 (file)
@@ -3,6 +3,7 @@
 #include "../warpzonelib/mathlib.qc"
 
 #include "accumulate.qh"
+#include "bits.qh"
 #include "counting.qh"
 #include "cvar.qh"
 #include "defer.qh"
@@ -18,8 +19,8 @@
 #include "oo.qh"
 #include "p2mathlib.qc"
 #include "player.qh"
-#include "prandom.qc"
 #include "progname.qh"
+#include "random.qc"
 #include "registry.qh"
 #include "replicate.qh"
 #include "sort.qh"
diff --git a/qcsrc/lib/bits.qh b/qcsrc/lib/bits.qh
new file mode 100644 (file)
index 0000000..86b5df5
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef BITS_H
+#define BITS_H
+
+#define BIT(n) (1 << (n))
+#define BITS(n) (BIT(n) - 1)
+#ifndef BRANCHLESS_BITSET
+    #define BITSET(var, mask, flag) (flag ? (var) | (mask) : (var) &~ (mask))
+#else
+    #define BITSET(var, mask, flag) ((var) ^ (-(flag) ^ (var)) & (mask))
+#endif
+
+int lowestbit(int f)
+{
+    f &= ~(f << 1);
+    f &= ~(f << 2);
+    f &= ~(f << 4);
+    f &= ~(f << 8);
+    f &= ~(f << 16);
+    return f;
+}
+
+#endif
index a8a5290..1a707a4 100644 (file)
@@ -3,23 +3,23 @@
 
 void mean_accumulate(entity e, .float a, .float c, float mean, float value, float weight)
 {
-       if (weight == 0)
-               return;
-       if (mean == 0)
-               e.(a) *= pow(value, weight);
-       else
-               e.(a) += pow(value, mean) * weight;
-       e.(c) += weight;
+    if (weight == 0)
+        return;
+    if (mean == 0)
+        e.(a) *= pow(value, weight);
+    else
+        e.(a) += pow(value, mean) * weight;
+    e.(c) += weight;
 }
 
 float mean_evaluate(entity e, .float a, .float c, float mean)
 {
-       if (e.(c) == 0)
-               return 0;
-       if (mean == 0)
-               return pow(e.(a), 1.0 / e.(c));
-       else
-               return pow(e.(a) / e.(c), 1.0 / mean);
+    if (e.(c) == 0)
+        return 0;
+    if (mean == 0)
+        return pow(e.(a), 1.0 / e.(c));
+    else
+        return pow(e.(a) / e.(c), 1.0 / mean);
 }
 
 #define MEAN_ACCUMULATE(prefix,v,w) mean_accumulate(self,prefix##_accumulator,prefix##_count,prefix##_mean,v,w)
@@ -33,9 +33,9 @@ crandom
 Returns a random number between -1.0 and 1.0
 ==================
 */
-float crandom (void)
+float crandom()
 {
-       return 2 * (random () - 0.5);
+    return 2 * (random() - 0.5);
 }
 
 
@@ -46,27 +46,16 @@ Angc used for animations
 */
 
 
-float angc (float a1, float a2)
+float angc(float a1, float a2)
 {
-       float   a;
-
-       while (a1 > 180)
-               a1 = a1 - 360;
-       while (a1 < -179)
-               a1 = a1 + 360;
-
-       while (a2 > 180)
-               a2 = a2 - 360;
-       while (a2 < -179)
-               a2 = a2 + 360;
-
-       a = a1 - a2;
-       while (a > 180)
-               a = a - 360;
-       while (a < -179)
-               a = a + 360;
-
-       return a;
+    while (a1 > 180) a1 -= 360;
+    while (a1 < -179) a1 += 360;
+    while (a2 > 180) a2 -= 360;
+    while (a2 < -179) a2 += 360;
+    float a = a1 - a2;
+    while (a > 180) a -= 360;
+    while (a < -179) a += 360;
+    return a;
 }
 
 float fsnap(float val,float fsize)
@@ -87,7 +76,208 @@ vector vsnap(vector point,float fsize)
 
 vector lerpv(float t0, vector v0, float t1, vector v1, float t)
 {
-       return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));
+    return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));
+}
+
+vector bezier_quadratic_getpoint(vector a, vector b, vector c, float t)
+{
+    return
+        (c - 2 * b + a) * (t * t) +
+        (b - a) * (2 * t) +
+        a;
+}
+
+vector bezier_quadratic_getderivative(vector a, vector b, vector c, float t)
+{
+    return
+        (c - 2 * b + a) * (2 * t) +
+        (b - a) * 2;
+}
+
+float cubic_speedfunc(float startspeedfactor, float endspeedfactor, float x)
+{
+    return
+        (((     startspeedfactor + endspeedfactor - 2
+        ) * x - 2 * startspeedfactor - endspeedfactor + 3
+        ) * x + startspeedfactor
+        ) * x;
+}
+
+bool cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor)
+{
+    if (startspeedfactor < 0 || endspeedfactor < 0)
+        return false;
+
+    /*
+    // if this is the case, the possible zeros of the first derivative are outside
+    // 0..1
+    We can calculate this condition as condition
+    if(se <= 3)
+        return true;
+    */
+
+    // better, see below:
+    if (startspeedfactor <= 3 && endspeedfactor <= 3)
+        return true;
+
+    // if this is the case, the first derivative has no zeros at all
+    float se = startspeedfactor + endspeedfactor;
+    float s_e = startspeedfactor - endspeedfactor;
+    if (3 * (se - 4) * (se - 4) + s_e * s_e <= 12) // an ellipse
+        return true;
+
+    // Now let s <= 3, s <= 3, s+e >= 3 (triangle) then we get se <= 6 (top right corner).
+    // we also get s_e <= 6 - se
+    // 3 * (se - 4)^2 + (6 - se)^2
+    // is quadratic, has value 12 at 3 and 6, and value < 12 in between.
+    // Therefore, above "better" check works!
+
+    return false;
+
+    // known good cases:
+    // (0, [0..3])
+    // (0.5, [0..3.8])
+    // (1, [0..4])
+    // (1.5, [0..3.9])
+    // (2, [0..3.7])
+    // (2.5, [0..3.4])
+    // (3, [0..3])
+    // (3.5, [0.2..2.3])
+    // (4, 1)
+
+    /*
+       On another note:
+       inflection point is always at (2s + e - 3) / (3s + 3e - 6).
+
+       s + e - 2 == 0: no inflection
+
+       s + e > 2:
+       0 < inflection < 1 if:
+       0 < 2s + e - 3 < 3s + 3e - 6
+       2s + e > 3 and 2e + s > 3
+
+       s + e < 2:
+       0 < inflection < 1 if:
+       0 > 2s + e - 3 > 3s + 3e - 6
+       2s + e < 3 and 2e + s < 3
+
+       Therefore: there is an inflection point iff:
+       e outside (3 - s)/2 .. 3 - s*2
+
+       in other words, if (s,e) in triangle (1,1)(0,3)(0,1.5) or in triangle (1,1)(3,0)(1.5,0)
+    */
+}
+
+/** continuous function mapping all reals into -1..1 */
+float float2range11(float f)
+{
+    return f / (fabs(f) + 1);
 }
 
+/** continuous function mapping all reals into 0..1 */
+float float2range01(float f)
+{
+    return 0.5 + 0.5 * float2range11(f);
+}
+
+float median(float a, float b, float c)
+{
+    return (a < c) ? bound(a, b, c) : bound(c, b, a);
+}
+
+float almost_equals(float a, float b)
+{
+    float eps = (max(a, -a) + max(b, -b)) * 0.001;
+    return a - b < eps && b - a < eps;
+}
+
+float almost_in_bounds(float a, float b, float c)
+{
+    float eps = (max(a, -a) + max(c, -c)) * 0.001;
+    if (a > c)
+        eps = -eps;
+    return b == median(a - eps, b, c + eps);
+}
+
+float power2of(float e)
+{
+    return pow(2, e);
+}
+
+float log2of(float x)
+{
+    // NOTE: generated code
+    if (x > 2048)
+        if (x > 131072)
+            if (x > 1048576)
+                if (x > 4194304)
+                    return 23;
+                else
+                    if (x > 2097152)
+                        return 22;
+                    else
+                        return 21;
+            else
+                if (x > 524288)
+                    return 20;
+                else
+                    if (x > 262144)
+                        return 19;
+                    else
+                        return 18;
+        else
+            if (x > 16384)
+                if (x > 65536)
+                    return 17;
+                else
+                    if (x > 32768)
+                        return 16;
+                    else
+                        return 15;
+            else
+                if (x > 8192)
+                    return 14;
+                else
+                    if (x > 4096)
+                        return 13;
+                    else
+                        return 12;
+    else
+        if (x > 32)
+            if (x > 256)
+                if (x > 1024)
+                    return 11;
+                else
+                    if (x > 512)
+                        return 10;
+                    else
+                        return 9;
+            else
+                if (x > 128)
+                    return 8;
+                else
+                    if (x > 64)
+                        return 7;
+                    else
+                        return 6;
+        else
+            if (x > 4)
+                if (x > 16)
+                    return 5;
+                else
+                    if (x > 8)
+                        return 4;
+                    else
+                        return 3;
+            else
+                if (x > 2)
+                    return 2;
+                else
+                    if (x > 1)
+                        return 1;
+                    else
+                        return 0;
+}
+
+
 #endif
index 2928ce8..04faffc 100644 (file)
@@ -118,4 +118,49 @@ STATIC_INIT(RegisterTempEntities_renumber) {
     }
 }
 
+#ifndef MENUQC
+#ifdef CSQC
+int ReadInt24_t()
+{
+    int v = ReadShort() << 8; // note: this is signed
+    v += ReadByte(); // note: this is unsigned
+    return v;
+}
+vector ReadInt48_t()
+{
+    vector v;
+    v.x = ReadInt24_t();
+    v.y = ReadInt24_t();
+    v.z = 0;
+    return v;
+}
+vector ReadInt72_t()
+{
+    vector v;
+    v.x = ReadInt24_t();
+    v.y = ReadInt24_t();
+    v.z = ReadInt24_t();
+    return v;
+}
+#else
+void WriteInt24_t(float dst, float val)
+{
+    float v;
+    WriteShort(dst, (v = floor(val >> 8)));
+    WriteByte(dst, val - (v << 8)); // 0..255
+}
+void WriteInt48_t(float dst, vector val)
+{
+    WriteInt24_t(dst, val.x);
+    WriteInt24_t(dst, val.y);
+}
+void WriteInt72_t(float dst, vector val)
+{
+    WriteInt24_t(dst, val.x);
+    WriteInt24_t(dst, val.y);
+    WriteInt24_t(dst, val.z);
+}
+#endif
+#endif
+
 #endif
diff --git a/qcsrc/lib/prandom.qc b/qcsrc/lib/prandom.qc
deleted file mode 100644 (file)
index 4f58822..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#include "prandom.qh"
-
-// prandom - PREDICTABLE random number generator (not seeded yet)
-
-#ifdef USE_PRANDOM
-float prandom_seed;
-float prandom()
-{
-       float c;
-       c = crc16(false, strcat(ftos(prandom_seed), ftos(prandom_seed + M_PI)));
-       prandom_seed = c;
-
-#ifdef USE_PRANDOM_DEBUG
-       LOG_TRACE("RANDOM -> ", ftos(c), "\n");
-#endif
-
-       return c / 65536; // in [0..1[
-}
-
-vector prandomvec()
-{
-       vector v;
-
-       do
-       {
-               v.x = prandom();
-               v.y = prandom();
-               v.z = prandom();
-       }
-       while(v * v > 1);
-
-       return v;
-}
-
-void psrandom(float seed)
-{
-       prandom_seed = seed;
-#ifdef USE_PRANDOM_DEBUG
-       LOG_TRACE("SRANDOM ", ftos(seed), "\n");
-#endif
-}
-
-#ifdef USE_PRANDOM_DEBUG
-void prandom_debug()
-{
-       LOG_TRACE("Current random seed = ", ftos(prandom_seed), "\n");
-}
-#endif
-#endif
diff --git a/qcsrc/lib/prandom.qh b/qcsrc/lib/prandom.qh
deleted file mode 100644 (file)
index a7653a5..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef PRANDOM_H
-#define PRANDOM_H
-
-// prandom - PREDICTABLE random number generator
-
-#define USE_PRANDOM
-
-#ifdef USE_PRANDOM
-float prandom();
-vector prandomvec();
-
-void psrandom(float seed);
-#ifdef USE_PRANDOM_DEBUG
-void prandom_debug();
-#else
-#define prandom_debug()
-#endif
-#else
-#define prandom random
-#define prandomvec randomvec
-#define psrandom(x)
-#define prandom_debug()
-#endif
-#endif
diff --git a/qcsrc/lib/random.qc b/qcsrc/lib/random.qc
new file mode 100644 (file)
index 0000000..149323b
--- /dev/null
@@ -0,0 +1,81 @@
+#include "random.qh"
+
+void RandomSelection_Init()
+{
+    RandomSelection_totalweight = 0;
+    RandomSelection_chosen_ent = NULL;
+    RandomSelection_chosen_float = 0;
+    RandomSelection_chosen_string = string_null;
+    RandomSelection_best_priority = -1;
+}
+
+void RandomSelection_Add(entity e, float f, string s, float weight, float priority)
+{
+    if (priority > RandomSelection_best_priority)
+    {
+        RandomSelection_best_priority = priority;
+        RandomSelection_chosen_ent = e;
+        RandomSelection_chosen_float = f;
+        RandomSelection_chosen_string = s;
+        RandomSelection_totalweight = weight;
+    }
+    else if (priority == RandomSelection_best_priority)
+    {
+        RandomSelection_totalweight += weight;
+        if (random() * RandomSelection_totalweight <= weight)
+        {
+            RandomSelection_chosen_ent = e;
+            RandomSelection_chosen_float = f;
+            RandomSelection_chosen_string = s;
+        }
+    }
+}
+
+
+// prandom - PREDICTABLE random number generator (not seeded yet)
+
+#ifdef USE_PRANDOM
+float prandom_seed;
+float prandom()
+{
+    float c;
+    c = crc16(false, strcat(ftos(prandom_seed), ftos(prandom_seed + M_PI)));
+    prandom_seed = c;
+
+#ifdef USE_PRANDOM_DEBUG
+    LOG_TRACE("RANDOM -> ", ftos(c), "\n");
+#endif
+
+    return c / 65536; // in [0..1[
+}
+
+vector prandomvec()
+{
+    vector v;
+
+    do
+    {
+        v.x = prandom();
+        v.y = prandom();
+        v.z = prandom();
+    }
+    while(v * v > 1);
+
+    return v;
+}
+
+void psrandom(float seed)
+{
+    prandom_seed = seed;
+#ifdef USE_PRANDOM_DEBUG
+    LOG_TRACE("SRANDOM ", ftos(seed), "\n");
+#endif
+}
+
+#ifdef USE_PRANDOM_DEBUG
+void prandom_debug()
+{
+    LOG_TRACE("Current random seed = ", ftos(prandom_seed), "\n");
+}
+#endif
+#endif
diff --git a/qcsrc/lib/random.qh b/qcsrc/lib/random.qh
new file mode 100644 (file)
index 0000000..551cf21
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef RANDOM_H
+#define RANDOM_H
+
+float RandomSelection_totalweight;
+float RandomSelection_best_priority;
+entity RandomSelection_chosen_ent;
+float RandomSelection_chosen_float;
+string RandomSelection_chosen_string;
+
+void RandomSelection_Init();
+void RandomSelection_Add(entity e, float f, string s, float weight, float priority);
+
+// prandom - PREDICTABLE random number generator
+
+#define USE_PRANDOM
+
+#ifdef USE_PRANDOM
+float prandom();
+vector prandomvec();
+
+void psrandom(float seed);
+#ifdef USE_PRANDOM_DEBUG
+void prandom_debug();
+#else
+#define prandom_debug()
+#endif
+#else
+#define prandom random
+#define prandomvec randomvec
+#define psrandom(x)
+#define prandom_debug()
+#endif
+#endif
index faf81b2..ede2edf 100644 (file)
@@ -4,12 +4,12 @@
 #ifndef SVQC
 float stringwidth_colors(string s, vector theSize)
 {
-       return stringwidth(s, true, theSize);
+    return stringwidth(s, true, theSize);
 }
 
 float stringwidth_nocolors(string s, vector theSize)
 {
-       return stringwidth(s, false, theSize);
+    return stringwidth(s, false, theSize);
 }
 #endif
 
@@ -18,21 +18,174 @@ float stringwidth_nocolors(string s, vector theSize)
 // TODO: macro
 string seconds_tostring(float sec)
 {
-       float minutes;
-       minutes = floor(sec / 60);
-
-       sec -= minutes * 60;
-       return sprintf("%d:%02d", minutes, sec);
+    float minutes = floor(sec / 60);
+    sec -= minutes * 60;
+    return sprintf("%d:%02d", minutes, sec);
 }
 
 int ColorTranslateMode;
 
 string ColorTranslateRGB(string s)
 {
-       if(ColorTranslateMode & 1)
-               return strdecolorize(s);
-       else
-               return s;
+    return (ColorTranslateMode & 1) ? strdecolorize(s) : s;
+}
+
+// color code replace, place inside of sprintf and parse the string... defaults described as constants
+// foreground/normal colors
+string autocvar_hud_colorset_foreground_1 = "2"; // F1 - Green  // primary priority (important names, etc)
+string autocvar_hud_colorset_foreground_2 = "3"; // F2 - Yellow // secondary priority (items, locations, numbers, etc)
+string autocvar_hud_colorset_foreground_3 = "4"; // F3 - Blue   // tertiary priority or relatively inconsequential text
+string autocvar_hud_colorset_foreground_4 = "1"; // F4 - Red    // notice/attention grabbing texting
+// "kill" colors
+string autocvar_hud_colorset_kill_1 = "1"; // K1 - Red    // "bad" or "dangerous" text (death messages against you, kill notifications, etc)
+string autocvar_hud_colorset_kill_2 = "3"; // K2 - Yellow // similar to above, but less important... OR, a highlight out of above message type
+string autocvar_hud_colorset_kill_3 = "4"; // K3 - Blue   // "good" or "beneficial" text (you fragging someone, etc)
+// background color
+string autocvar_hud_colorset_background = "7"; // BG - White // neutral/unimportant text
+
+/** color code replace, place inside of sprintf and parse the string */
+string CCR(string input)
+{
+    // See the autocvar declarations in util.qh for default values
+
+    // foreground/normal colors
+    input = strreplace("^F1", strcat("^", autocvar_hud_colorset_foreground_1), input);
+    input = strreplace("^F2", strcat("^", autocvar_hud_colorset_foreground_2), input);
+    input = strreplace("^F3", strcat("^", autocvar_hud_colorset_foreground_3), input);
+    input = strreplace("^F4", strcat("^", autocvar_hud_colorset_foreground_4), input);
+
+    // "kill" colors
+    input = strreplace("^K1", strcat("^", autocvar_hud_colorset_kill_1), input);
+    input = strreplace("^K2", strcat("^", autocvar_hud_colorset_kill_2), input);
+    input = strreplace("^K3", strcat("^", autocvar_hud_colorset_kill_3), input);
+
+    // background colors
+    input = strreplace("^BG", strcat("^", autocvar_hud_colorset_background), input);
+    input = strreplace("^N", "^7", input); // "none"-- reset to white...
+    return input;
+}
+
+bool startsWith(string haystack, string needle)
+{
+    return substring(haystack, 0, strlen(needle)) == needle;
+}
+
+bool startsWithNocase(string haystack, string needle)
+{
+    return strcasecmp(substring(haystack, 0, strlen(needle)), needle) == 0;
+}
+
+/** unzone the string, and return it as tempstring. Safe to be called on string_null */
+string fstrunzone(string s)
+{
+    if (!s) return s;
+    string sc = strcat(s, "");
+    strunzone(s);
+    return sc;
+}
+
+string car(string s)
+{
+    int o = strstrofs(s, " ", 0);
+    if (o < 0) return s;
+    return substring(s, 0, o);
+}
+
+string cdr(string s)
+{
+    int o = strstrofs(s, " ", 0);
+    if (o < 0) return string_null;
+    return substring(s, o + 1, strlen(s) - (o + 1));
+}
+
+string substring_range(string s, float b, float e)
+{
+    return substring(s, b, e - b);
+}
+
+string swapwords(string str, float i, float j)
+{
+    float n;
+    string s1, s2, s3, s4, s5;
+    float si, ei, sj, ej, s0, en;
+    n = tokenizebyseparator(str, " "); // must match g_maplist processing in ShuffleMaplist and "shuffle"
+    si = argv_start_index(i);
+    sj = argv_start_index(j);
+    ei = argv_end_index(i);
+    ej = argv_end_index(j);
+    s0 = argv_start_index(0);
+    en = argv_end_index(n-1);
+    s1 = substring_range(str, s0, si);
+    s2 = substring_range(str, si, ei);
+    s3 = substring_range(str, ei, sj);
+    s4 = substring_range(str, sj, ej);
+    s5 = substring_range(str, ej, en);
+    return strcat(s1, s4, s3, s2, s5);
+}
+
+string _shufflewords_str;
+void _shufflewords_swapfunc(float i, float j, entity pass)
+{
+    _shufflewords_str = swapwords(_shufflewords_str, i, j);
+}
+string shufflewords(string str)
+{
+    _shufflewords_str = str;
+    int n = tokenizebyseparator(str, " ");
+    shuffle(n, _shufflewords_swapfunc, NULL);
+    str = _shufflewords_str;
+    _shufflewords_str = string_null;
+    return str;
+}
+
+string unescape(string in)
+{
+    in = strzone(in); // but it doesn't seem to be necessary in my tests at least
+
+    int len = strlen(in);
+    string str = "";
+    for (int i = 0; i < len; ++i) {
+        string s = substring(in, i, 1);
+        if (s == "\\") {
+            s = substring(in, i + 1, 1);
+            if (s == "n")
+                str = strcat(str, "\n");
+            else if (s == "\\")
+                str = strcat(str, "\\");
+            else
+                str = strcat(str, substring(in, i, 2));
+            ++i;
+            continue;
+        }
+        str = strcat(str, s);
+    }
+    strunzone(in);
+    return str;
+}
+
+string strwords(string s, int w)
+{
+    int endpos = 0;
+    for (; w && endpos >= 0; --w) endpos = strstrofs(s, " ", endpos + 1);
+    if (endpos < 0) return s;
+    return substring(s, 0, endpos);
+}
+
+bool strhasword(string s, string w)
+{
+    return strstrofs(strcat(" ", s, " "), strcat(" ", w, " "), 0) >= 0;
+}
+
+int u8_strsize(string s)
+{
+    int l = 0;
+    for (int i = 0, c; (c = str2chr(s, i)) > 0; ++i, ++l)
+    {
+        l += (c >= 0x80);
+        l += (c >= 0x800);
+        l += (c >= 0x10000);
+    }
+    return l;
 }
 
 #endif
index d81a795..b57e27a 100644 (file)
@@ -7,28 +7,86 @@ const vector eZ = '0 0 1';
 
 vector randompos(vector m1, vector m2)
 {
-       vector v;
-       m2 = m2 - m1;
-       v_x = m2_x * random() + m1_x;
-       v_y = m2_y * random() + m1_y;
-       v_z = m2_z * random() + m1_z;
-       return  v;
+    vector v;
+    m2 = m2 - m1;
+    v_x = m2_x * random() + m1_x;
+    v_y = m2_y * random() + m1_y;
+    v_z = m2_z * random() + m1_z;
+    return     v;
 }
 
 float vlen2d(vector v)
 {
-       return sqrt(v.x * v.x + v.y * v.y);
+    return sqrt(v.x * v.x + v.y * v.y);
 }
 
 float vlen_maxnorm2d(vector v)
 {
-       return max(v.x, v.y, -v.x, -v.y);
+    return max(v.x, v.y, -v.x, -v.y);
 }
 
 float vlen_minnorm2d(vector v)
 {
-       return min(max(v.x, -v.x), max(v.y, -v.y));
+    return min(max(v.x, -v.x), max(v.y, -v.y));
 }
 
+float dist_point_line(vector p, vector l0, vector ldir)
+{
+    ldir = normalize(ldir);
+
+    // remove the component in line direction
+    p = p - (p * ldir) * ldir;
+
+    // vlen of the remaining vector
+    return vlen(p);
+}
+
+/** requires that m2>m1 in all coordinates, and that m4>m3 */
+float boxesoverlap(vector m1, vector m2, vector m3, vector m4) {return m2_x >= m3_x && m1_x <= m4_x && m2_y >= m3_y && m1_y <= m4_y && m2_z >= m3_z && m1_z <= m4_z;}
+
+/** requires the same as boxesoverlap, but is a stronger condition */
+float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) {return smins.x >= bmins.x && smaxs.x <= bmaxs.x && smins.y >= bmins.y && smaxs.y <= bmaxs.y && smins.z >= bmins.z && smaxs.z <= bmaxs.z;}
+
+
+vector vec2(vector v)
+{
+    v.z = 0;
+    return v;
+}
+
+vector vec3(float x, float y, float z)
+{
+    vector v; v.x = x; v.y = y; v.z = z;
+    return v;
+}
+
+#ifndef MENUQC
+vector get_corner_position(entity box, int corner)
+{
+    switch (corner) {
+        case 1: return vec3(box.absmin.x, box.absmin.y, box.absmin.z);
+        case 2: return vec3(box.absmax.x, box.absmin.y, box.absmin.z);
+        case 3: return vec3(box.absmin.x, box.absmax.y, box.absmin.z);
+        case 4: return vec3(box.absmin.x, box.absmin.y, box.absmax.z);
+        case 5: return vec3(box.absmax.x, box.absmax.y, box.absmin.z);
+        case 6: return vec3(box.absmin.x, box.absmax.y, box.absmax.z);
+        case 7: return vec3(box.absmax.x, box.absmin.y, box.absmax.z);
+        case 8: return vec3(box.absmax.x, box.absmax.y, box.absmax.z);
+        default: return '0 0 0';
+    }
+}
+
+vector NearestPointOnBox(entity box, vector org)
+{
+    vector m1 = box.mins + box.origin;
+    vector m2 = box.maxs + box.origin;
+
+    vector ret;
+    ret.x = bound(m1.x, org.x, m2.x);
+    ret.y = bound(m1.y, org.y, m2.y);
+    ret.z = bound(m1.z, org.z, m2.z);
+    return ret;
+}
+#endif
 
 #endif
index d6ffeeb..a0f9a3f 100644 (file)
@@ -1000,22 +1000,6 @@ string Map_Filename(float position)
        return strcat("maps/", argv(position), ".bsp");
 }
 
-string strwords(string s, float w)
-{
-       float endpos;
-       for(endpos = 0; w && endpos >= 0; --w)
-               endpos = strstrofs(s, " ", endpos + 1);
-       if(endpos < 0)
-               return s;
-       else
-               return substring(s, 0, endpos);
-}
-
-float strhasword(string s, string w)
-{
-       return strstrofs(strcat(" ", s, " "), strcat(" ", w, " "), 0) >= 0;
-}
-
 void Map_MarkAsRecent(string m)
 {
        cvar_set("g_maplist_mostrecent", strwords(strcat(m, " ", autocvar_g_maplist_mostrecent), max(0, autocvar_g_maplist_mostrecent_count)));