#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
}
#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)
+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';
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))
}
}
-// 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;
}
-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 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)
{
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)
{
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;
-}
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
string xencode(float f);
float xdecode(string s);
-int lowestbit(float f);
-
#ifdef CSQC
entity ReadCSQCEntity();
#endif
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__
#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
);
// 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)
#include "../warpzonelib/mathlib.qc"
#include "accumulate.qh"
+#include "bits.qh"
#include "counting.qh"
#include "cvar.qh"
#include "defer.qh"
#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"
--- /dev/null
+#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
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)
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);
}
*/
-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)
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
}
}
+#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
+++ /dev/null
-#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
+++ /dev/null
-#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
--- /dev/null
+#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
--- /dev/null
+#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
#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
// 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
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
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)));