]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/util.qc
Disallow enabling r_water via mapinfo, automatically enable it on maps with warpzones...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / util.qc
index d83871080d1f19167fd803096f8ef03efd2cb11f..a7e9c42104d222e04d7b6d1d5884c6376eb7b060 100644 (file)
 #include "util.qh"
 
 #if defined(CSQC)
-    #include "../client/defs.qh"
     #include "constants.qh"
-       #include "../client/mutators/events.qh"
+       #include <client/mutators/_mod.qh>
     #include "mapinfo.qh"
     #include "notifications/all.qh"
+       #include "scores.qh"
     #include <common/deathtypes/all.qh>
 #elif defined(MENUQC)
 #elif defined(SVQC)
     #include "constants.qh"
-    #include "../server/autocvars.qh"
-    #include "../server/defs.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.
 */
 vector real_origin(entity ent)
 {
-       entity e;
        vector v = ((ent.absmin + ent.absmax) * 0.5);
+       entity e = ent.tag_entity;
 
-       e = ent.tag_entity;
        while(e)
        {
                v = v + ((e.absmin + e.absmax) * 0.5);
@@ -184,6 +304,7 @@ void depthfirst(entity start, .entity up, .entity downleft, .entity right, void(
        }
 }
 
+#ifdef GAMEQC
 string ScoreString(int pFlags, float pValue)
 {
        string valstr;
@@ -215,6 +336,7 @@ string ScoreString(int pFlags, float pValue)
 
        return valstr;
 }
+#endif
 
 // compressed vector format:
 // like MD3, just even shorter
@@ -326,7 +448,7 @@ float compressShortVector(vector vec)
 STATIC_INIT(compressShortVector)
 {
        float l = 1;
-       float f = pow(2, 1/8);
+       float f = (2 ** (1/8));
        int i;
        for(i = 0; i < 128; ++i)
        {
@@ -336,17 +458,18 @@ STATIC_INIT(compressShortVector)
 
        if(cvar("developer"))
        {
-               LOG_INFO("Verifying vector compression table...\n");
+               LOG_TRACE("Verifying vector compression table...");
                for(i = 0x0F00; i < 0xFFFF; ++i)
                        if(i != compressShortVector(decompressShortVector(i)))
                        {
-                               LOG_INFO("BROKEN vector compression: ", ftos(i));
-                               LOG_INFO(" -> ", vtos(decompressShortVector(i)));
-                               LOG_INFO(" -> ", ftos(compressShortVector(decompressShortVector(i))));
-                               LOG_INFO("\n");
-                               error("b0rk");
+                               LOG_FATALF(
+                                   "BROKEN vector compression: %s -> %s -> %s",
+                                   ftos(i),
+                                   vtos(decompressShortVector(i)),
+                                   ftos(compressShortVector(decompressShortVector(i)))
+                );
                        }
-               LOG_INFO("Done.\n");
+               LOG_TRACE("Done.");
        }
 }
 
@@ -414,11 +537,11 @@ string fixPriorityList(string order, float from, float to, float subtract, float
 string mapPriorityList(string order, string(string) mapfunc)
 {
        string neworder;
-       float i, n;
+       float n;
 
        n = tokenize_console(order);
        neworder = "";
-       for(i = 0; i < n; ++i)
+       for(float i = 0; i < n; ++i)
                neworder = strcat(neworder, mapfunc(argv(i)), " ");
 
        return substring(neworder, 0, strlen(neworder) - 1);
@@ -426,15 +549,12 @@ string mapPriorityList(string order, string(string) mapfunc)
 
 string swapInPriorityList(string order, float i, float j)
 {
-       string s;
-       float w, n;
-
-       n = tokenize_console(order);
+       float n = tokenize_console(order);
 
        if(i >= 0 && i < n && j >= 0 && j < n && i != j)
        {
-               s = "";
-               for(w = 0; w < n; ++w)
+               string s = "";
+               for(float w = 0; w < n; ++w)
                {
                        if(w == i)
                                s = strcat(s, argv(j), " ");
@@ -454,14 +574,12 @@ void get_mi_min_max(float mode)
 {
        vector mi, ma;
 
-       if(mi_shortname)
-               strunzone(mi_shortname);
-       mi_shortname = mapname;
-       if(!strcasecmp(substring(mi_shortname, 0, 5), "maps/"))
-               mi_shortname = substring(mi_shortname, 5, strlen(mi_shortname) - 5);
-       if(!strcasecmp(substring(mi_shortname, strlen(mi_shortname) - 4, 4), ".bsp"))
-               mi_shortname = substring(mi_shortname, 0, strlen(mi_shortname) - 4);
-       mi_shortname = strzone(mi_shortname);
+       string s = mapname;
+       if(!strcasecmp(substring(s, 0, 5), "maps/"))
+               s = substring(s, 5, strlen(s) - 5);
+       if(!strcasecmp(substring(s, strlen(s) - 4, 4), ".bsp"))
+               s = substring(s, 0, strlen(s) - 4);
+       strcpy(mi_shortname, s);
 
 #ifdef CSQC
        mi = world.mins;
@@ -599,7 +717,7 @@ float cvar_settemp(string tmp_cvar, string tmp_value)
 
        if(!cvar_type(tmp_cvar))
        {
-               LOG_INFOF("Error: cvar %s doesn't exist!\n", tmp_cvar);
+               LOG_INFOF("Error: cvar %s doesn't exist!", tmp_cvar);
                return 0;
        }
 
@@ -641,7 +759,7 @@ int cvar_settemp_restore()
                        ++j;
                }
                else
-                       LOG_INFOF("Error: cvar %s doesn't exist anymore! It can still be restored once it's manually recreated.\n", it.netname);
+                       LOG_INFOF("Error: cvar %s doesn't exist anymore! It can still be restored once it's manually recreated.", it.netname);
        });
 
 #else
@@ -655,7 +773,7 @@ int cvar_settemp_restore()
                        ++j;
                }
                else
-                       print(sprintf("Error: cvar %s doesn't exist anymore! It can still be restored once it's manually recreated.\n", e.netname));
+                       print(sprintf("Error: cvar %s doesn't exist anymore! It can still be restored once it's manually recreated.", e.netname));
        }
 #endif
 
@@ -672,7 +790,6 @@ bool isCaretEscaped(string theText, float pos)
 
 int skipIncompleteTag(string theText, float pos, int len)
 {
-       int i = 0, ch = 0;
        int tag_start = -1;
 
        if(substring(theText, pos - 1, 1) == "^")
@@ -680,7 +797,7 @@ int skipIncompleteTag(string theText, float pos, int len)
                if(isCaretEscaped(theText, pos - 1) || pos >= len)
                        return 0;
 
-               ch = str2chr(theText, pos);
+               int ch = str2chr(theText, pos);
                if(ch >= '0' && ch <= '9')
                        return 1; // ^[0-9] color code found
                else if (ch == 'x')
@@ -690,7 +807,7 @@ int skipIncompleteTag(string theText, float pos, int len)
        }
        else
        {
-               for(i = 2; pos - i >= 0 && i <= 4; ++i)
+               for(int i = 2; pos - i >= 0 && i <= 4; ++i)
                {
                        if(substring(theText, pos - i, 2) == "^x")
                        {
@@ -784,8 +901,7 @@ string find_last_color_code(string s)
        if (start == -1) // no caret found
                return "";
        int len = strlen(s)-1;
-       int i;
-       for(i = len; i >= start; --i)
+       for(int i = len; i >= start; --i)
        {
                if(substring(s, i, 1) != "^")
                        continue;
@@ -1078,17 +1194,17 @@ float compressShotOrigin(vector v)
        float rz = rint(v.z * 4) + 128;
        if(rx > 255 || rx < 0)
        {
-               LOG_INFO("shot origin ", vtos(v), " x out of bounds\n");
+               LOG_DEBUG("shot origin ", vtos(v), " x out of bounds\n");
                rx = bound(0, rx, 255);
        }
        if(ry > 255 || ry < 0)
        {
-               LOG_INFO("shot origin ", vtos(v), " y out of bounds\n");
+               LOG_DEBUG("shot origin ", vtos(v), " y out of bounds\n");
                ry = bound(0, ry, 255);
        }
        if(rz > 255 || rz < 0)
        {
-               LOG_INFO("shot origin ", vtos(v), " z out of bounds\n");
+               LOG_DEBUG("shot origin ", vtos(v), " z out of bounds\n");
                rz = bound(0, rz, 255);
        }
        return rx * 0x10000 + ry * 0x100 + rz;
@@ -1132,6 +1248,8 @@ vector healtharmor_applydamage(float a, float armorblock, int deathtype, float d
        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;
@@ -1180,6 +1298,7 @@ float matchacl(string acl, string str)
                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;
@@ -1367,7 +1486,7 @@ void m_shutdown()
 {
        if(shutdown_running)
        {
-               LOG_INFO("Recursive shutdown detected! Only restoring cvars...\n");
+               LOG_INFO("Recursive shutdown detected! Only restoring cvars...");
        }
        else
        {
@@ -1400,8 +1519,7 @@ 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;
+               strfree(to_execute_next_frame);
        }
 }
 void queue_to_execute_next_frame(string s)
@@ -1409,9 +1527,8 @@ 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);
+       strcpy(to_execute_next_frame, s);
 }
 
 .float FindConnectedComponent_processing;