]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/sv_main.qc
Merge branch 'master' into terencehill/bot_waypoints
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / sv_main.qc
index 87430a93eff4502037e10c52e8dd511f820e1852..34f3cdc21b63e6d405b5a9306fe432c8c78bb0ba 100644 (file)
@@ -217,8 +217,6 @@ void StartFrame()
        if (timeout_status == TIMEOUT_LEADTIME) // just before the timeout (when timeout_status will be TIMEOUT_ACTIVE)
                orig_slowmo = autocvar_slowmo; // slowmo will be restored after the timeout
 
-       skill = autocvar_skill;
-
        // detect when the pre-game countdown (if any) has ended and the game has started
        bool game_delay = (time < game_starttime);
        if (autocvar_sv_eventlog && game_delay_last && !game_delay)
@@ -247,6 +245,77 @@ void StartFrame()
 .string gametypefilter;
 .string cvarfilter;
 bool DoesQ3ARemoveThisEntity(entity this);
+
+/**
+ * Evaluate an expression of the form: [+ | -]? [var[op]val | [op]var | val | var] ...
+ * +: all must match. this is the default
+ * -: one must NOT match
+ *
+ * var>x
+ * var<x
+ * var>=x
+ * var<=x
+ * var==x
+ * var!=x
+ * var===x
+ * var!==x
+ */
+bool expr_evaluate(string s)
+{
+    bool ret = false;
+    if (str2chr(s, 0) == '+') {
+        s = substring(s, 1, -1);
+    } else if (str2chr(s, 0) == '-') {
+        ret = true;
+        s = substring(s, 1, -1);
+    }
+    bool expr_fail = false;
+    for (int i = 0, n = tokenize_console(s); i < n; ++i) {
+        int o;
+        string k, v;
+        s = argv(i);
+        #define X(expr) \
+            if (expr) { \
+                continue; \
+            } else { \
+                expr_fail = true; \
+                break; \
+            }
+        #define BINOP(op, len, expr) \
+            if ((o = strstrofs(s, op, 0)) >= 0) { \
+                k = substring(s, 0, o); \
+                v = substring(s, o + len, -1); \
+                X(expr); \
+            }
+        BINOP(">=", 2, cvar(k) >= stof(v));
+        BINOP("<=", 2, cvar(k) <= stof(v));
+        BINOP(">",  1, cvar(k) >  stof(v));
+        BINOP("<",  1, cvar(k) <  stof(v));
+        BINOP("==", 2, cvar(k) == stof(v));
+        BINOP("!=", 2, cvar(k) != stof(v));
+        BINOP("===", 3, cvar_string(k) == v);
+        BINOP("!==", 3, cvar_string(k) != v);
+        {
+            k = s;
+            bool b = true;
+            if (str2chr(k, 0) == '!') {
+                k = substring(s, 1, -1);
+                b = false;
+            }
+            float f = stof(k);
+            bool isnum = ftos(f) == k;
+            X(boolean(isnum ? f : cvar(k)) == b);
+        }
+        #undef BINOP
+        #undef X
+    }
+    if (!expr_fail) {
+        ret = !ret;
+    }
+    // now ret is true if we want to keep the item, and false if we want to get rid of it
+    return ret;
+}
+
 void SV_OnEntityPreSpawnFunction(entity this)
 {
        __spawnfunc_expecting = true;
@@ -257,65 +326,8 @@ void SV_OnEntityPreSpawnFunction(entity this)
        {
                goto cleanup;
        }
-       if (this.cvarfilter != "") {
-               bool inv = false;
-
-               string s = this.cvarfilter;
-               if (str2chr(s, 0) == '+') {
-                       s = substring(s, 1, -1);
-               } else if(str2chr(s, 0) == '-') {
-                       inv = true;
-                       s = substring(s, 1, -1);
-               }
-
-        bool cvar_fail = false;
-               for (int i = 0, n = tokenize_console(s); i < n; ++i) {
-                   int o;
-            string k, v;
-                       s = argv(i);
-                       // syntax:
-                       // var>x
-                       // var<x
-                       // var>=x
-                       // var<=x
-                       // var==x
-                       // var!=x
-                       // var===x
-                       // var!==x
-                       #define X(expr) \
-                           if (expr) { \
-                    continue; \
-                } else { \
-                    cvar_fail = true; \
-                    break; \
-                }
-                       #define BINOP(op, len, expr) \
-                           if ((o = strstrofs(s, op, 0)) >= 0) { \
-                    k = substring(s, 0, o); \
-                    v = substring(s, o + len, -1); \
-                    X(expr); \
-                }
-            BINOP(">=", 2, cvar(k) >= stof(v));
-            BINOP("<=", 2, cvar(k) <= stof(v));
-            BINOP(">",  1, cvar(k) >  stof(v));
-            BINOP("<",  1, cvar(k) <  stof(v));
-            BINOP("==", 2, cvar(k) == stof(v));
-            BINOP("!=", 2, cvar(k) != stof(v));
-            // fixme: did these two ever work?
-            BINOP("===", 2, cvar_string(k) == v);
-            BINOP("!==", 2, cvar_string(k) != v);
-            if (str2chr(s, 0) == '!') { k = substring(s, 1, -1); X(!cvar(k)); }
-            { k = s; X(cvar(k)); }
-                       #undef BINOP
-                       #undef X
-               }
-               if (!cvar_fail) {
-                   inv = !inv;
-               }
-               // now inv is true if we want to keep the item, and false if we want to get rid of it
-               if (!inv) {
-                       goto cleanup;
-               }
+       if (this.cvarfilter != "" && !expr_evaluate(this.cvarfilter)) {
+        goto cleanup;
        }
 
        if (DoesQ3ARemoveThisEntity(this)) {
@@ -355,6 +367,9 @@ LABEL(cleanup)
 void WarpZone_PostInitialize_Callback()
 {
        // create waypoint links for warpzones
+       entity tracetest_ent = spawn();
+       setsize(tracetest_ent, PL_MIN_CONST, PL_MAX_CONST);
+       tracetest_ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
        //for(entity e = warpzone_first; e; e = e.warpzone_next)
        for(entity e = NULL; (e = find(e, classname, "trigger_warpzone")); )
        {
@@ -365,6 +380,7 @@ void WarpZone_PostInitialize_Callback()
                dst = (e.enemy.absmin + e.enemy.absmax) * 0.5;
                makevectors(e.enemy.warpzone_angles);
                dst = dst + ((e.enemy.warpzone_origin - dst) * v_forward) * v_forward - 16 * v_right;
-               waypoint_spawnforteleporter_v(e, src, dst, 0);
+               waypoint_spawnforteleporter_wz(e, src, dst, 0, -v_up, tracetest_ent);
        }
+       delete(tracetest_ent);
 }