]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/util.qc
csqc items (needed for simple items)
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / util.qc
index 5e7845bbc4f3c42d80cb06a5e006df8af2330c17..582777647c9fcd2e2798baa4c695ecea269d3969 100644 (file)
@@ -39,6 +39,16 @@ void wordwrap_sprint(string s, float l)
 #endif
 #endif
 
+#ifndef SVQC
+string draw_UseSkinFor(string pic)
+{
+       if(substring(pic, 0, 1) == "/")
+               return substring(pic, 1, strlen(pic)-1);
+       else
+               return strcat(draw_currentSkin, "/", pic);
+}
+#endif
+
 string unescape(string in)
 {
        float i, len;
@@ -186,6 +196,9 @@ float median(float a, float b, float c)
 // works for up to 10 decimals!
 string ftos_decimals(float number, float decimals)
 {
+       // inhibit stupid negative zero
+       if(number == 0)
+               number = 0;
        // we have sprintf...
        return sprintf("%.*f", decimals, number);
 }
@@ -195,21 +208,21 @@ vector colormapPaletteColor(float c, float isPants)
 {
        switch(c)
        {
-               case  0: return '0.800000 0.800000 0.800000';
-               case  1: return '0.600000 0.400000 0.000000';
+               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.658824 1.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.600000 0.600000 0.600000';
+               case 11: return '0.000000 0.000000 1.000000';
                case 12: return '1.000000 1.000000 0.000000';
-               case 13: return '0.000000 0.313725 1.000000';
-               case 14: return '1.000000 0.501961 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
@@ -396,27 +409,6 @@ void buf_save(float buf, string pFilename)
        fclose(fh);
 }
 
-string GametypeNameFromType(float g)
-{
-       if      (g == GAME_DEATHMATCH) return "dm";
-       else if (g == GAME_TEAM_DEATHMATCH) return "tdm";
-       else if (g == GAME_DOMINATION) return "dom";
-       else if (g == GAME_CTF) return "ctf";
-       else if (g == GAME_RUNEMATCH) return "rune";
-       else if (g == GAME_LMS) return "lms";
-       else if (g == GAME_ARENA) return "arena";
-       else if (g == GAME_CA) return "ca";
-       else if (g == GAME_KEYHUNT) return "kh";
-       else if (g == GAME_ONSLAUGHT) return "ons";
-       else if (g == GAME_ASSAULT) return "as";
-       else if (g == GAME_RACE) return "rc";
-       else if (g == GAME_NEXBALL) return "nexball";
-       else if (g == GAME_CTS) return "cts";
-       else if (g == GAME_FREEZETAG) return "freezetag";
-       else if (g == GAME_KEEPAWAY) return "ka";
-       return "dm";
-}
-
 string mmsss(float tenths)
 {
        float minutes;
@@ -920,6 +912,8 @@ 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);
 }
 
@@ -1430,7 +1424,7 @@ string textShortenToLength(string theText, float maxWidth, textLengthUpToLength_
 float isGametypeInFilter(float gt, float tp, float ts, string pattern)
 {
        string subpattern, subpattern2, subpattern3, subpattern4;
-       subpattern = strcat(",", GametypeNameFromType(gt), ",");
+       subpattern = strcat(",", MapInfo_Type_ToString(gt), ",");
        if(tp)
                subpattern2 = ",teams,";
        else
@@ -1439,7 +1433,7 @@ float isGametypeInFilter(float gt, float tp, float ts, string pattern)
                subpattern3 = ",teamspawns,";
        else
                subpattern3 = ",noteamspawns,";
-       if(gt == GAME_RACE || gt == GAME_CTS)
+       if(gt == MAPINFO_TYPE_RACE || gt == MAPINFO_TYPE_CTS)
                subpattern4 = ",race,";
        else
                subpattern4 = string_null;
@@ -1591,6 +1585,10 @@ void check_unacceptable_compiler_bugs()
        tokenize_console("foo bar");
        if(strcat(argv(0), substring("foo bar", 4, 7 - argv_start_index(1))) == "barbar")
                error("fteqcc bug introduced with revision 3178 detected. Please upgrade fteqcc to a later revision, downgrade fteqcc to revision 3177, or pester Spike until he fixes it. You can set _allow_unacceptable_compiler_bugs 1 to skip this check, but expect stuff to be horribly broken then.");
+
+       string s = "";
+       if not(s)
+               error("The empty string counts as false. We do not want that!");
 }
 
 float compressShotOrigin(vector v)
@@ -2185,3 +2183,77 @@ void m_shutdown()
        }
        cvar_settemp_restore(); // this must be done LAST, but in any case
 }
+
+#define APPROXPASTTIME_ACCURACY_REQUIREMENT 0.05
+#define APPROXPASTTIME_MAX (16384 * APPROXPASTTIME_ACCURACY_REQUIREMENT)
+#define APPROXPASTTIME_RANGE (64 * APPROXPASTTIME_ACCURACY_REQUIREMENT)
+// this will use the value:
+//   128
+// accuracy near zero is APPROXPASTTIME_MAX/(256*255)
+// accuracy at x is 1/derivative, i.e.
+//   APPROXPASTTIME_MAX * (1 + 256 * (dt / APPROXPASTTIME_MAX))^2 / 65536
+#ifdef SVQC
+void WriteApproxPastTime(float dst, float t)
+{
+       float dt = time - t;
+
+       // warning: this is approximate; do not resend when you don't have to!
+       // be careful with sendflags here!
+       // we want: 0 -> 0.05, 1 -> 0.1, ..., 255 -> 12.75
+
+       // map to range...
+       dt = 256 * (dt / ((APPROXPASTTIME_MAX / 256) + dt));
+
+       // round...
+       dt = rint(bound(0, dt, 255));
+
+       WriteByte(dst, dt);
+}
+#endif
+#ifdef CSQC
+float ReadApproxPastTime()
+{
+       float dt = ReadByte();
+
+       // map from range...PPROXPASTTIME_MAX / 256
+       dt = (APPROXPASTTIME_MAX / 256) * (dt / (256 - dt));
+
+       return servertime - dt;
+}
+#endif
+
+#ifndef MENUQC
+.float skeleton_bones_index;
+void Skeleton_SetBones(entity e)
+{
+       // set skeleton_bones to the total number of bones on the model
+       if(e.skeleton_bones_index == e.modelindex)
+               return; // same model, nothing to update
+
+       float skelindex;
+       skelindex = skel_create(e.modelindex);
+       e.skeleton_bones = skel_get_numbones(skelindex);
+       skel_delete(skelindex);
+       e.skeleton_bones_index = e.modelindex;
+}
+#endif
+
+string to_execute_next_frame;
+void execute_next_frame()
+{
+       if(to_execute_next_frame)
+       {
+               localcmd("\n", to_execute_next_frame, "\n");
+               strunzone(to_execute_next_frame);
+               to_execute_next_frame = string_null;
+       }
+}
+void queue_to_execute_next_frame(string s)
+{
+       if(to_execute_next_frame)
+       {
+               s = strcat(s, "\n", to_execute_next_frame);
+               strunzone(to_execute_next_frame);
+       }
+       to_execute_next_frame = strzone(s);
+}