]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/sv_main.qc
Merge branch 'master' into Lyberta/TeamplayOverhaul
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / sv_main.qc
index 7d27e0298a97d82678a48678c000c86c97ac2c65..487ab1fc533821590ab49c18fdeffb7cf24dd686 100644 (file)
@@ -37,9 +37,9 @@ void CreatureFrame_hotliquids(entity this)
                if (this.flags & FL_PROJECTILE)
                {
                        if (this.watertype == CONTENT_LAVA)
-                               Damage (this, NULL, NULL, autocvar_g_balance_contents_projectiledamage * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_LAVA.m_id, this.origin, '0 0 0');
+                               Damage (this, NULL, NULL, autocvar_g_balance_contents_projectiledamage * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_LAVA.m_id, DMG_NOWEP, this.origin, '0 0 0');
                        else if (this.watertype == CONTENT_SLIME)
-                               Damage (this, NULL, NULL, autocvar_g_balance_contents_projectiledamage * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_SLIME.m_id, this.origin, '0 0 0');
+                               Damage (this, NULL, NULL, autocvar_g_balance_contents_projectiledamage * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_SLIME.m_id, DMG_NOWEP, this.origin, '0 0 0');
                }
                else
                {
@@ -50,7 +50,7 @@ void CreatureFrame_hotliquids(entity this)
                                        this.watersound_finished = time + 0.5;
                                        sound (this, CH_PLAYER_SINGLE, SND_LAVA, VOL_BASE, ATTEN_NORM);
                                }
-                               Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_lava * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_LAVA.m_id, this.origin, '0 0 0');
+                               Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_lava * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_LAVA.m_id, DMG_NOWEP, this.origin, '0 0 0');
                                if(autocvar_g_balance_contents_playerdamage_lava_burn)
                                        Fire_AddDamage(this, NULL, autocvar_g_balance_contents_playerdamage_lava_burn * this.waterlevel, autocvar_g_balance_contents_playerdamage_lava_burn_time * this.waterlevel, DEATH_LAVA.m_id);
                        }
@@ -61,7 +61,7 @@ void CreatureFrame_hotliquids(entity this)
                                        this.watersound_finished = time + 0.5;
                                        sound (this, CH_PLAYER_SINGLE, SND_SLIME, VOL_BASE, ATTEN_NORM);
                                }
-                               Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_slime * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_SLIME.m_id, this.origin, '0 0 0');
+                               Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_slime * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_SLIME.m_id, DMG_NOWEP, this.origin, '0 0 0');
                        }
                }
        }
@@ -88,7 +88,6 @@ void CreatureFrame_Liquids(entity this)
                        this.dmgtime = 0;
                }
                this.air_finished = time + 12;
-               this.dmg = 2;
        }
 }
 
@@ -117,16 +116,19 @@ void CreatureFrame_FallDamage(entity this)
                        else
                                dm = min((dm - autocvar_g_balance_falldamage_minspeed) * autocvar_g_balance_falldamage_factor, autocvar_g_balance_falldamage_maxdamage);
                        if (dm > 0)
-                               Damage (this, NULL, NULL, dm, DEATH_FALL.m_id, this.origin, '0 0 0');
+                               Damage (this, NULL, NULL, dm, DEATH_FALL.m_id, DMG_NOWEP, this.origin, '0 0 0');
                }
 
                if(autocvar_g_maxspeed > 0 && velocity_len > autocvar_g_maxspeed)
-                       Damage (this, NULL, NULL, 100000, DEATH_SHOOTING_STAR.m_id, this.origin, '0 0 0');
+                       Damage (this, NULL, NULL, 100000, DEATH_SHOOTING_STAR.m_id, DMG_NOWEP, this.origin, '0 0 0');
        }
 }
 
 void CreatureFrame_All()
 {
+       if(game_stopped || time < game_starttime)
+               return;
+
        IL_EACH(g_damagedbycontents, it.damagedbycontents,
        {
                if (it.move_movetype == MOVETYPE_NOCLIP) continue;
@@ -217,8 +219,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,75 +247,87 @@ 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;
-       __spawnfunc_expect = this;
        if (this)
        if (this.gametypefilter != "")
        if (!isGametypeInFilter(MapInfo_LoadedGametype, teamplay, have_team_spawns, this.gametypefilter))
        {
                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)) {
@@ -349,12 +361,14 @@ void SV_OnEntityPreSpawnFunction(entity this)
        return;
 LABEL(cleanup)
     delete(this);
-    __spawnfunc_expecting = false;
 }
 
 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 +379,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);
 }