#include "util.qh"
#if defined(CSQC)
- #include "constants.qh"
#include <client/mutators/_mod.qh>
- #include "mapinfo.qh"
- #include "notifications/all.qh"
- #include "scores.qh"
- #include <common/deathtypes/all.qh>
+ #include <common/constants.qh>
+ #include <common/deathtypes/all.qh>
#include <common/gamemodes/_mod.qh>
+ #include <common/mapinfo.qh>
+ #include <common/notifications/all.qh>
+ #include <common/scores.qh>
#elif defined(MENUQC)
#elif defined(SVQC)
- #include "constants.qh"
- #include <server/mutators/_mod.qh>
- #include "notifications/all.qh"
- #include <common/deathtypes/all.qh>
+ #include <common/constants.qh>
+ #include <common/deathtypes/all.qh>
#include <common/gamemodes/_mod.qh>
- #include "scores.qh"
- #include "mapinfo.qh"
+ #include <common/mapinfo.qh>
+ #include <common/notifications/all.qh>
+ #include <common/scores.qh>
+ #include <server/mutators/_mod.qh>
#endif
#ifdef SVQC
return j;
}
-bool isCaretEscaped(string theText, float pos)
-{
- int i = 0;
- while(pos - i >= 1 && substring(theText, pos - i - 1, 1) == "^")
- ++i;
- return (i & 1);
-}
-
-int skipIncompleteTag(string theText, float pos, int len)
-{
- int tag_start = -1;
-
- if(substring(theText, pos - 1, 1) == "^")
- {
- if(isCaretEscaped(theText, pos - 1) || pos >= len)
- return 0;
-
- int ch = str2chr(theText, pos);
- if(ch >= '0' && ch <= '9')
- return 1; // ^[0-9] color code found
- else if (ch == 'x')
- tag_start = pos - 1; // ^x tag found
- else
- return 0;
- }
- else
- {
- for(int i = 2; pos - i >= 0 && i <= 4; ++i)
- {
- if(substring(theText, pos - i, 2) == "^x")
- {
- tag_start = pos - i; // ^x tag found
- break;
- }
- }
- }
-
- if(tag_start >= 0)
- {
- if(tag_start + 5 < len)
- if(IS_HEXDIGIT(substring(theText, tag_start + 2, 1)))
- if(IS_HEXDIGIT(substring(theText, tag_start + 3, 1)))
- if(IS_HEXDIGIT(substring(theText, tag_start + 4, 1)))
- {
- if(!isCaretEscaped(theText, tag_start))
- return 5 - (pos - tag_start); // ^xRGB color code found
- }
- }
- return 0;
-}
-
float textLengthUpToWidth(string theText, float maxWidth, vector theSize, textLengthUpToWidth_widthFunction_t w)
{
// STOP.
{
middle = floor((left + right) / 2);
if(colors)
- ofs = skipIncompleteTag(theText, middle, len);
+ {
+ vector res = checkColorCode(theText, len, middle, false);
+ ofs = (res.x) ? res.x - res.y : 0;
+ }
+
if(w(substring(theText, 0, middle + ofs), theSize) <= maxWidth)
left = middle + ofs;
else
{
middle = floor((left + right) / 2);
if(colors)
- ofs = skipIncompleteTag(theText, middle, len);
+ {
+ vector res = checkColorCode(theText, len, middle, true);
+ ofs = (!res.x) ? 0 : res.x - res.y;
+ }
+
if(w(substring(theText, 0, middle + ofs)) <= maxWidth)
left = middle + ofs;
else
string getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunction_t tw)
{
- float cantake;
- float take;
- string s;
-
- s = getWrappedLine_remaining;
+ string s = getWrappedLine_remaining;
if(w <= 0)
{
return s; // the line has no size ANYWAY, nothing would be displayed.
}
- cantake = textLengthUpToWidth(s, w, theFontSize, tw);
- if(cantake > 0 && cantake < strlen(s))
+ int take_until = textLengthUpToWidth(s, w, theFontSize, tw);
+ if(take_until > 0 && take_until < strlen(s))
{
- take = cantake - 1;
- while(take > 0 && substring(s, take, 1) != " ")
- --take;
- if(take == 0)
- {
- getWrappedLine_remaining = substring(s, cantake, strlen(s) - cantake);
- if(getWrappedLine_remaining == "")
- getWrappedLine_remaining = string_null;
- else if (tw("^7", theFontSize) == 0)
- getWrappedLine_remaining = strcat(find_last_color_code(substring(s, 0, cantake)), getWrappedLine_remaining);
- return substring(s, 0, cantake);
- }
- else
+ int last_word = take_until - 1;
+ while(last_word > 0 && substring(s, last_word, 1) != " ")
+ --last_word;
+
+ int skip = 0;
+ if(last_word != 0)
{
- getWrappedLine_remaining = substring(s, take + 1, strlen(s) - take);
- if(getWrappedLine_remaining == "")
- getWrappedLine_remaining = string_null;
- else if (tw("^7", theFontSize) == 0)
- getWrappedLine_remaining = strcat(find_last_color_code(substring(s, 0, take)), getWrappedLine_remaining);
- return substring(s, 0, take);
+ take_until = last_word;
+ skip = 1;
}
+
+ getWrappedLine_remaining = substring(s, take_until + skip, strlen(s) - take_until);
+ if(getWrappedLine_remaining == "")
+ getWrappedLine_remaining = string_null;
+ else if (tw("^7", theFontSize) == 0)
+ getWrappedLine_remaining = strcat(find_last_color_code(substring(s, 0, take_until)), getWrappedLine_remaining);
+ return substring(s, 0, take_until);
}
else
{
string getWrappedLineLen(float w, textLengthUpToLength_lenFunction_t tw)
{
- float cantake;
- float take;
- string s;
-
- s = getWrappedLine_remaining;
+ string s = getWrappedLine_remaining;
if(w <= 0)
{
return s; // the line has no size ANYWAY, nothing would be displayed.
}
- cantake = textLengthUpToLength(s, w, tw);
- if(cantake > 0 && cantake < strlen(s))
+ int take_until = textLengthUpToLength(s, w, tw);
+ if(take_until > 0 && take_until < strlen(s))
{
- take = cantake - 1;
- while(take > 0 && substring(s, take, 1) != " ")
- --take;
- if(take == 0)
- {
- getWrappedLine_remaining = substring(s, cantake, strlen(s) - cantake);
- if(getWrappedLine_remaining == "")
- getWrappedLine_remaining = string_null;
- else if (tw("^7") == 0)
- getWrappedLine_remaining = strcat(find_last_color_code(substring(s, 0, cantake)), getWrappedLine_remaining);
- return substring(s, 0, cantake);
- }
- else
+ int last_word = take_until - 1;
+ while(last_word > 0 && substring(s, last_word, 1) != " ")
+ --last_word;
+
+ int skip = 0;
+ if(last_word != 0)
{
- getWrappedLine_remaining = substring(s, take + 1, strlen(s) - take);
- if(getWrappedLine_remaining == "")
- getWrappedLine_remaining = string_null;
- else if (tw("^7") == 0)
- getWrappedLine_remaining = strcat(find_last_color_code(substring(s, 0, take)), getWrappedLine_remaining);
- return substring(s, 0, take);
+ take_until = last_word;
+ skip = 1;
}
+
+ getWrappedLine_remaining = substring(s, take_until + skip, strlen(s) - take_until);
+ if(getWrappedLine_remaining == "")
+ getWrappedLine_remaining = string_null;
+ else if (tw("^7") == 0)
+ getWrappedLine_remaining = strcat(find_last_color_code(substring(s, 0, take_until)), getWrappedLine_remaining);
+ return substring(s, 0, take_until);
}
else
{
void write_String_To_File(int fh, string str, bool alsoprint)
{
fputs(fh, str);
- if (alsoprint) LOG_INFO(str);
+ if (alsoprint) LOG_HELP(str);
}
string get_model_datafilename(string m, float sk, string fil)
}
break;
}
- case CNT_IDLE:
- {
- switch(num)
- {
- case 10: return ANNCE_NUM_IDLE_10;
- case 9: return ANNCE_NUM_IDLE_9;
- case 8: return ANNCE_NUM_IDLE_8;
- case 7: return ANNCE_NUM_IDLE_7;
- case 6: return ANNCE_NUM_IDLE_6;
- case 5: return ANNCE_NUM_IDLE_5;
- case 4: return ANNCE_NUM_IDLE_4;
- case 3: return ANNCE_NUM_IDLE_3;
- case 2: return ANNCE_NUM_IDLE_2;
- case 1: return ANNCE_NUM_IDLE_1;
- }
- break;
- }
case CNT_KILL:
{
switch(num)
}
break;
}
+ case CNT_NORMAL:
default:
{
switch(num)
ent.v_angle = ent.angles - e.angles; // relative angles
ent.aiment_classname = strzone(e.classname);
ent.aiment_deadflag = e.deadflag;
+
+ if(IS_PLAYER(ent.aiment))
+ {
+ entity pl = ent.aiment;
+ ent.view_ofs.x = bound(pl.mins.x + 4, ent.view_ofs.x, pl.maxs.x - 4);
+ ent.view_ofs.y = bound(pl.mins.y + 4, ent.view_ofs.y, pl.maxs.y - 4);
+ ent.view_ofs.z = bound(pl.mins.z + 4, ent.view_ofs.z, pl.maxs.z - 4);
+ }
}
+
void UnsetMovetypeFollow(entity ent)
{
set_movetype(ent, MOVETYPE_FLY);
PROJECTILE_MAKETRIGGER(ent);
- ent.aiment = NULL;
+ if (ent.aiment_classname)
+ strunzone(ent.classname);
+ // FIXME: engine bug?
+ // resetting aiment the engine will set orb's origin close to world's origin
+ //ent.aiment = NULL;
}
-float LostMovetypeFollow(entity ent)
+
+int LostMovetypeFollow(entity ent)
{
/*
if(ent.move_movetype != MOVETYPE_FOLLOW)
if(ent.aiment)
error("???");
*/
- if(ent.aiment)
- {
- if(ent.aiment.classname != ent.aiment_classname)
- return 1;
- if(ent.aiment.deadflag != ent.aiment_deadflag)
- return 1;
- }
+ // FIXME: engine bug?
+ // when aiment disconnects the engine will set orb's origin close to world's origin
+ if(!ent.aiment)
+ return 2;
+ if(ent.aiment.classname != ent.aiment_classname || ent.aiment.deadflag != ent.aiment_deadflag)
+ return 1;
return 0;
}
#endif
return trace_hits_box(start, end, thmi - ma, thma - mi);
}
#endif
+
+ERASEABLE
+float cvar_or(string cv, float v)
+{
+ string s = cvar_string(cv);
+ if(s == "")
+ return v;
+ else
+ return stof(s);
+}
+
+// NOTE base is the central value
+// freq: circle frequency, = 2*pi*frequency in hertz
+// start_pos:
+// -1 start from the lower value
+// 0 start from the base value
+// 1 start from the higher value
+ERASEABLE
+float blink_synced(float base, float range, float freq, float start_time, int start_pos)
+{
+ // note:
+ // RMS = sqrt(base^2 + 0.5 * range^2)
+ // thus
+ // base = sqrt(RMS^2 - 0.5 * range^2)
+ // ensure RMS == 1
+
+ return base + range * sin((time - start_time - (M_PI / 2) * start_pos) * freq);
+}
+
+ERASEABLE
+float blink(float base, float range, float freq)
+{
+ return blink_synced(base, range, freq, 0, 0);
+}