#include "util.qh"
#if defined(CSQC)
- #include "../dpdefs/csprogsdefs.qh"
#include "../client/defs.qh"
#include "constants.qh"
#include "../client/mutators/events.qh"
#include "mapinfo.qh"
#include "notifications.qh"
- #include "deathtypes.qh"
+ #include "deathtypes/all.qh"
#elif defined(MENUQC)
#elif defined(SVQC)
- #include "../dpdefs/progsdefs.qh"
- #include "../dpdefs/dpextensions.qh"
#include "constants.qh"
#include "../server/autocvars.qh"
#include "../server/defs.qh"
#include "../server/mutators/events.qh"
#include "notifications.qh"
- #include "deathtypes.qh"
+ #include "deathtypes/all.qh"
#include "mapinfo.qh"
#endif
}
#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;
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;
}
}
-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)
return sprintf("%.*f", decimals, number);
}
-vector colormapPaletteColor(float c, float isPants)
-{
- switch(c)
- {
- case 0: return '1.000000 1.000000 1.000000';
- case 1: return '1.000000 0.333333 0.000000';
- case 2: return '0.000000 1.000000 0.501961';
- case 3: return '0.000000 1.000000 0.000000';
- case 4: return '1.000000 0.000000 0.000000';
- case 5: return '0.000000 0.666667 1.000000';
- case 6: return '0.000000 1.000000 1.000000';
- case 7: return '0.501961 1.000000 0.000000';
- case 8: return '0.501961 0.000000 1.000000';
- case 9: return '1.000000 0.000000 1.000000';
- case 10: return '1.000000 0.000000 0.501961';
- case 11: return '0.000000 0.000000 1.000000';
- case 12: return '1.000000 1.000000 0.000000';
- case 13: return '0.000000 0.333333 1.000000';
- case 14: return '1.000000 0.666667 0.000000';
- case 15:
- 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))
- + '0 0 1' * (0.502 + 0.498 * sin(time / 2.7182818285 + 4.1887902048));
- else
- return
- '1 0 0' * (0.502 + 0.498 * sin(time / 3.1415926536 + 5.2359877560))
- + '0 1 0' * (0.502 + 0.498 * sin(time / 3.1415926536 + 3.1415926536))
- + '0 0 1' * (0.502 + 0.498 * sin(time / 3.1415926536 + 1.0471975512));
- default: return '0.000 0.000 0.000';
- }
-}
-
-// 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)
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)
);
}
-// 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.
return 1;
}
-void shuffle(float n, swapfunc_t swap, entity pass)
-{
- float i, j;
- for(i = 1; i < n; ++i)
- {
- // swap i-th item at a random position from 0 to i
- // proof for even distribution:
- // n = 1: obvious
- // n -> n+1:
- // item n+1 gets at any position with chance 1/(n+1)
- // all others will get their 1/n chance reduced by factor n/(n+1)
- // to be on place n+1, their chance will be 1/(n+1)
- // 1/n * n/(n+1) = 1/(n+1)
- // q.e.d.
- j = floor(random() * (i + 1));
- if(j != i)
- swap(j, i, pass);
- }
-}
-
-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;
return v;
}
-void heapsort(float n, swapfunc_t swap, comparefunc_t cmp, entity pass)
-{
- float start, end, root, child;
-
- // heapify
- start = floor((n - 2) / 2);
- while(start >= 0)
- {
- // siftdown(start, count-1);
- root = start;
- while(root * 2 + 1 <= n-1)
- {
- child = root * 2 + 1;
- if(child < n-1)
- if(cmp(child, child+1, pass) < 0)
- ++child;
- if(cmp(root, child, pass) < 0)
- {
- swap(root, child, pass);
- root = child;
- }
- else
- break;
- }
- // end of siftdown
- --start;
- }
-
- // extract
- end = n - 1;
- while(end > 0)
- {
- swap(0, end, pass);
- --end;
- // siftdown(0, end);
- root = 0;
- while(root * 2 + 1 <= end)
- {
- child = root * 2 + 1;
- if(child < end && cmp(child, child+1, pass) < 0)
- ++child;
- if(cmp(root, child, pass) < 0)
- {
- swap(root, child, pass);
- root = child;
- }
- else
- break;
- }
- // end of siftdown
- }
-}
-
-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)
{
// NOTE: we'll always choose the SMALLER value...
float healthdamage, armordamage, armorideal;
- if (deathtype == DEATH_DROWN) // Why should armor help here...
+ if (DEATH_IS(deathtype, DEATH_DROWN)) // Why should armor help here...
armorblock = 0;
vector v;
healthdamage = (h - 1) / (1 - armorblock); // damage we can take if we could use more health
vector healtharmor_applydamage(float a, float armorblock, int deathtype, float damage)
{
vector v;
- if (deathtype == DEATH_DROWN) // Why should armor help here...
+ if (DEATH_IS(deathtype, DEATH_DROWN)) // Why should armor help here...
armorblock = 0;
v.y = bound(0, damage * armorblock, a); // save
v.x = bound(0, damage - v.y, damage); // take
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;
}
}
-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;
}
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)
{
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;
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";
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)
{
return strcat(substring(input, 0, (strlen(input) - strlen(truncation))), truncation);
}*/
-// escape the string to make it safe for consoles
-string MakeConsoleSafe(string input)
-{
- input = strreplace("\n", "", input);
- input = strreplace("\\", "\\\\", input);
- input = strreplace("$", "$$", input);
- input = strreplace("\"", "\\\"", input);
- return input;
-}
-
#ifdef CSQC
entity ReadCSQCEntity()
{
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)
{
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)
{
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;
-}