#if defined(CSQC)
#include "constants.qh"
- #include "../client/mutators/events.qh"
+ #include <client/mutators/_mod.qh>
#include "mapinfo.qh"
#include "notifications/all.qh"
#include "scores.qh"
#elif defined(MENUQC)
#elif defined(SVQC)
#include "constants.qh"
- #include "../server/mutators/events.qh"
+ #include <server/mutators/_mod.qh>
#include "notifications/all.qh"
#include <common/deathtypes/all.qh>
#include "scores.qh"
#include "mapinfo.qh"
#endif
+#ifdef SVQC
+float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomonsters, entity forent, float stopatentity, entity ignorestopatentity) // returns the number of traces done, for benchmarking
+{
+ vector pos, dir, t;
+ float nudge;
+ entity stopentity;
+
+ //nudge = 2 * cvar("collision_impactnudge"); // why not?
+ nudge = 0.5;
+
+ dir = normalize(v2 - v1);
+
+ pos = v1 + dir * nudge;
+
+ float c;
+ c = 0;
+
+ for (;;)
+ {
+ if(pos * dir >= v2 * dir)
+ {
+ // went too far
+ trace_fraction = 1;
+ trace_endpos = v2;
+ return c;
+ }
+
+ tracebox(pos, mi, ma, v2, nomonsters, forent);
+ ++c;
+
+ if(c == 50)
+ {
+ LOG_TRACE("When tracing from ", vtos(v1), " to ", vtos(v2));
+ LOG_TRACE(" Nudging gets us nowhere at ", vtos(pos));
+ LOG_TRACE(" trace_endpos is ", vtos(trace_endpos));
+ LOG_TRACE(" trace distance is ", ftos(vlen(pos - trace_endpos)));
+ }
+
+ stopentity = trace_ent;
+
+ if(trace_startsolid)
+ {
+ // we started inside solid.
+ // then trace from endpos to pos
+ t = trace_endpos;
+ tracebox(t, mi, ma, pos, nomonsters, forent);
+ ++c;
+ if(trace_startsolid)
+ {
+ // t is still inside solid? bad
+ // force advance, then, and retry
+ pos = t + dir * nudge;
+
+ // but if we hit an entity, stop RIGHT before it
+ if(stopatentity && stopentity && stopentity != ignorestopatentity)
+ {
+ trace_ent = stopentity;
+ trace_endpos = t;
+ trace_fraction = ((trace_endpos - v1) * dir) / ((v2 - v1) * dir);
+ return c;
+ }
+ }
+ else
+ {
+ // we actually LEFT solid!
+ trace_fraction = ((trace_endpos - v1) * dir) / ((v2 - v1) * dir);
+ return c;
+ }
+ }
+ else
+ {
+ // pos is outside solid?!? but why?!? never mind, just return it.
+ trace_endpos = pos;
+ trace_fraction = ((trace_endpos - v1) * dir) / ((v2 - v1) * dir);
+ return c;
+ }
+ }
+}
+
+void traceline_inverted (vector v1, vector v2, float nomonsters, entity forent, float stopatentity, entity ignorestopatentity)
+{
+ tracebox_inverted(v1, '0 0 0', '0 0 0', v2, nomonsters, forent, stopatentity, ignorestopatentity);
+}
+#endif
+
#ifdef GAMEQC
+/*
+==================
+findbetterlocation
+
+Returns a point at least 12 units away from walls
+(useful for explosion animations, although the blast is performed where it really happened)
+Ripped from DPMod
+==================
+*/
+vector findbetterlocation (vector org, float mindist)
+{
+ vector vec = mindist * '1 0 0';
+ int c = 0;
+ while (c < 6)
+ {
+ traceline (org, org + vec, true, NULL);
+ vec = vec * -1;
+ if (trace_fraction < 1)
+ {
+ vector loc = trace_endpos;
+ traceline (loc, loc + vec, true, NULL);
+ if (trace_fraction >= 1)
+ org = loc + vec;
+ }
+ if (c & 1)
+ {
+ float h = vec.y;
+ vec.y = vec.x;
+ vec.x = vec.z;
+ vec.z = h;
+ }
+ c = c + 1;
+ }
+
+ return org;
+}
+
/*
* Get "real" origin, in worldspace, even if ent is attached to something else.
*/
s = strzone(s);
lleft = l;
- for (i = 0;i < strlen(s);++i)
+ int len = strlen(s);
+ for (i = 0; i < len; ++i)
{
if (substring(s, i, 2) == "\\n")
{
if (lleft > 0)
{
callback(" ");
- lleft = lleft - 1;
+ --lleft;
}
}
else
{
- for (j = i+1;j < strlen(s);++j)
+ for (j = i+1; j < len; ++j)
// ^^ this skips over the first character of a word, which
// is ALWAYS part of the word
// this is safe since if i+1 == strlen(s), i will become
lleft = l;
}
callback(substring(s, i, wlen));
- lleft = lleft - wlen;
+ lleft -= wlen;
i = j - 1;
}
}
vector v;
if (DEATH_IS(deathtype, DEATH_DROWN)) // Why should armor help here...
armorblock = 0;
+ if (deathtype & HITTYPE_ARMORPIERCE)
+ armorblock = 0;
v.y = bound(0, damage * armorblock, a); // save
v.x = bound(0, damage - v.y, damage); // take
v.z = 0;
if(s == t)
{
r = d;
+ break; // if we found a killing case, apply it! other settings may be allowed in the future, but this one is caught
}
}
return r;
}
+ERASEABLE
+void write_String_To_File(int fh, string str, bool alsoprint)
+{
+ fputs(fh, str);
+ if (alsoprint) LOG_INFO(str);
+}
+
string get_model_datafilename(string m, float sk, string fil)
{
if(m)
case "reserved": get_model_parameters_species = SPECIES_RESERVED; break;
}
if(c == "sex")
+ {
+ if (s == "Male") s = _("Male");
+ else if (s == "Female") s = _("Female");
+ else if (s == "Undisclosed") s = _("Undisclosed");
get_model_parameters_sex = s;
+ }
if(c == "weight")
get_model_parameters_weight = stof(s);
if(c == "age")
return 1;
}
+string translate_key(string key)
+{
+ if (prvm_language == "en") return key;
+
+ if (substring(key, 0, 1) == "<")
+ {
+ if (key == "<KEY NOT FOUND>") return _("<KEY NOT FOUND>");
+ if (key == "<UNKNOWN KEYNUM>") return _("<UNKNOWN KEYNUM>");
+ }
+
+ switch(key)
+ {
+ case "TAB": return _("TAB");
+ case "ENTER": return _("ENTER");
+ case "ESCAPE": return _("ESCAPE");
+ case "SPACE": return _("SPACE");
+
+ case "BACKSPACE": return _("BACKSPACE");
+ case "UPARROW": return _("UPARROW");
+ case "DOWNARROW": return _("DOWNARROW");
+ case "LEFTARROW": return _("LEFTARROW");
+ case "RIGHTARROW": return _("RIGHTARROW");
+
+ case "ALT": return _("ALT");
+ case "CTRL": return _("CTRL");
+ case "SHIFT": return _("SHIFT");
+
+ case "INS": return _("INS");
+ case "DEL": return _("DEL");
+ case "PGDN": return _("PGDN");
+ case "PGUP": return _("PGUP");
+ case "HOME": return _("HOME");
+ case "END": return _("END");
+
+ case "PAUSE": return _("PAUSE");
+
+ case "NUMLOCK": return _("NUMLOCK");
+ case "CAPSLOCK": return _("CAPSLOCK");
+ case "SCROLLOCK": return _("SCROLLOCK");
+
+ case "SEMICOLON": return _("SEMICOLON");
+ case "TILDE": return _("TILDE");
+ case "BACKQUOTE": return _("BACKQUOTE");
+ case "QUOTE": return _("QUOTE");
+ case "APOSTROPHE": return _("APOSTROPHE");
+ case "BACKSLASH": return _("BACKSLASH");
+ }
+
+ if (substring(key, 0, 1) == "F")
+ {
+ string subkey = substring(key, 1, -1);
+ if (IS_DIGIT(substring(key, 3, 1))) // check only first digit
+ {
+ return sprintf(_("F%d"), stof(subkey));
+ }
+ // continue in case there is another key name starting with F
+ }
+
+ if (substring(key, 0, 3) == "KP_")
+ {
+ string subkey = substring(key, 3, -1);
+ if (IS_DIGIT(substring(key, 3, 1))) // check only first digit
+ {
+ return sprintf(_("KP_%d"), stof(subkey));
+ }
+
+ switch(subkey)
+ {
+ case "INS": return sprintf(_("KP_%s"), _("INS"));
+ case "END": return sprintf(_("KP_%s"), _("END"));
+ case "DOWNARROW": return sprintf(_("KP_%s"), _("DOWNARROW"));
+ case "PGDN": return sprintf(_("KP_%s"), _("PGDN"));
+ case "LEFTARROW": return sprintf(_("KP_%s"), _("LEFTARROW"));
+ case "RIGHTARROW": return sprintf(_("KP_%s"), _("RIGHTARROW"));
+ case "HOME": return sprintf(_("KP_%s"), _("HOME"));
+ case "UPARROW": return sprintf(_("KP_%s"), _("UPARROW"));
+ case "PGUP": return sprintf(_("KP_%s"), _("PGUP"));
+ case "PERIOD": return sprintf(_("KP_%s"), _("PERIOD"));
+ case "DEL": return sprintf(_("KP_%s"), _("DEL"));
+ case "DIVIDE": return sprintf(_("KP_%s"), _("DIVIDE"));
+ case "SLASH": return sprintf(_("KP_%s"), _("SLASH"));
+ case "MULTIPLY": return sprintf(_("KP_%s"), _("MULTIPLY"));
+ case "MINUS": return sprintf(_("KP_%s"), _("MINUS"));
+ case "PLUS": return sprintf(_("KP_%s"), _("PLUS"));
+ case "ENTER": return sprintf(_("KP_%s"), _("ENTER"));
+ case "EQUALS": return sprintf(_("KP_%s"), _("EQUALS"));
+ default: return key;
+ }
+ }
+
+ if (key == "PRINTSCREEN") return _("PRINTSCREEN");
+
+ if (substring(key, 0, 5) == "MOUSE")
+ return sprintf(_("MOUSE%d"), stof(substring(key, 5, -1)));
+
+ if (key == "MWHEELUP") return _("MWHEELUP");
+ if (key == "MWHEELDOWN") return _("MWHEELDOWN");
+
+ if (substring(key, 0,3) == "JOY")
+ return sprintf(_("JOY%d"), stof(substring(key, 3, -1)));
+
+ if (substring(key, 0,3) == "AUX")
+ return sprintf(_("AUX%d"), stof(substring(key, 3, -1)));
+
+ if (substring(key, 0, 4) == "X360_")
+ {
+ string subkey = substring(key, 4, -1);
+ switch(subkey)
+ {
+ case "DPAD_UP": return sprintf(_("X360_%s"), _("DPAD_UP"));
+ case "DPAD_DOWN": return sprintf(_("X360_%s"), _("DPAD_DOWN"));
+ case "DPAD_LEFT": return sprintf(_("X360_%s"), _("DPAD_LEFT"));
+ case "DPAD_RIGHT": return sprintf(_("X360_%s"), _("DPAD_RIGHT"));
+ case "START": return sprintf(_("X360_%s"), _("START"));
+ case "BACK": return sprintf(_("X360_%s"), _("BACK"));
+ case "LEFT_THUMB": return sprintf(_("X360_%s"), _("LEFT_THUMB"));
+ case "RIGHT_THUMB": return sprintf(_("X360_%s"), _("RIGHT_THUMB"));
+ case "LEFT_SHOULDER": return sprintf(_("X360_%s"), _("LEFT_SHOULDER"));
+ case "RIGHT_SHOULDER": return sprintf(_("X360_%s"), _("RIGHT_SHOULDER"));
+ case "LEFT_TRIGGER": return sprintf(_("X360_%s"), _("LEFT_TRIGGER"));
+ case "RIGHT_TRIGGER": return sprintf(_("X360_%s"), _("RIGHT_TRIGGER"));
+ case "LEFT_THUMB_UP": return sprintf(_("X360_%s"), _("LEFT_THUMB_UP"));
+ case "LEFT_THUMB_DOWN": return sprintf(_("X360_%s"), _("LEFT_THUMB_DOWN"));
+ case "LEFT_THUMB_LEFT": return sprintf(_("X360_%s"), _("LEFT_THUMB_LEFT"));
+ case "LEFT_THUMB_RIGHT": return sprintf(_("X360_%s"), _("LEFT_THUMB_RIGHT"));
+ case "RIGHT_THUMB_UP": return sprintf(_("X360_%s"), _("RIGHT_THUMB_UP"));
+ case "RIGHT_THUMB_DOWN": return sprintf(_("X360_%s"), _("RIGHT_THUMB_DOWN"));
+ case "RIGHT_THUMB_LEFT": return sprintf(_("X360_%s"), _("RIGHT_THUMB_LEFT"));
+ case "RIGHT_THUMB_RIGHT": return sprintf(_("X360_%s"), _("RIGHT_THUMB_RIGHT"));
+ default: return key;
+ }
+ }
+
+ if (substring(key, 0, 4) == "JOY_")
+ {
+ string subkey = substring(key, 4, -1);
+ switch(subkey)
+ {
+ case "UP": return sprintf(_("JOY_%s"), _("UP"));
+ case "DOWN": return sprintf(_("JOY_%s"), _("DOWN"));
+ case "LEFT": return sprintf(_("JOY_%s"), _("LEFT"));
+ case "RIGHT": return sprintf(_("JOY_%s"), _("RIGHT"));
+ default: return key;
+ }
+ }
+
+ if (substring(key, 0, 8) == "MIDINOTE")
+ return sprintf(_("MIDINOTE%d"), stof(substring(key, 8, -1)));
+
+ return key;
+}
+
// x-encoding (encoding as zero length invisible string)
const string XENCODE_2 = "xX";
const string XENCODE_22 = "0123456789abcdefABCDEF";