]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/main.qc
Transifex autosync
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / main.qc
index 7c010ad86ad29214bf6f377411339b5b463dbde6..b0433b9ea5990b5131a759f544a63e404d2de8ca 100644 (file)
@@ -59,6 +59,11 @@ bool dropclient_schedule(entity this)
        setthink(e, dropclient_do);
        e.owner = this;
        e.nextthink = time + 0.1;
+
+       // ignore this player for team balancing and queuing
+       this.team = -1;
+       this.wants_join = 0;
+       this.classname = STR_OBSERVER;
        return true;
 }
 
@@ -294,16 +299,13 @@ void systems_update();
 void sys_phys_update(entity this, float dt);
 void StartFrame()
 {
-       IL_EACH(g_moveables, it.last_pushed,
+       FOREACH_CLIENT(IS_FAKE_CLIENT(it),
        {
-               if(!WarpZoneLib_ExactTrigger_Touch(it.last_pushed, it, false))
-                       it.last_pushed = NULL;
+               // DP calls these for real clients only
+               sys_phys_update(it, frametime); // called by SV_PlayerPhysics for players
+               PlayerPreThink(it);
        });
 
-       // TODO: if move is more than 50ms, split it into two moves (this matches QWSV behavior and the client prediction)
-       IL_EACH(g_players, IS_FAKE_CLIENT(it), sys_phys_update(it, frametime));
-       IL_EACH(g_players, IS_FAKE_CLIENT(it), PlayerPreThink(it));
-
        execute_next_frame();
 
        delete_fn = remove_unsafely; // not during spawning!
@@ -371,8 +373,13 @@ void StartFrame()
        MUTATOR_CALLHOOK(SV_StartFrame);
 
        GlobalStats_updateglobal();
-       FOREACH_CLIENT(true, GlobalStats_update(it));
-       IL_EACH(g_players, IS_FAKE_CLIENT(it), PlayerPostThink(it));
+       FOREACH_CLIENT(true,
+       {
+               GlobalStats_update(it);
+               if (IS_FAKE_CLIENT(it))
+                       PlayerPostThink(it); // DP calls this for real clients only
+               PlayerFrame(it);
+       });
 }
 
 .vector originjitter;
@@ -427,27 +434,25 @@ void SV_OnEntityPreSpawnFunction(entity this)
        }
 }
 
-string GetField_fullspawndata(entity e, string f, ...)
-/* Retrieves the value of a map entity field from fullspawndata
+/** Retrieves the value of a map entity field from fullspawndata.
  * This bypasses field value changes made by the engine,
  * eg string-to-float and escape sequence substitution.
  *
  * Avoids the need to declare fields just to read them once :)
  *
  * Returns the last instance of the field to match DarkPlaces behaviour.
- * Path support: converts \ to / and tests the file if a third (bool, true) arg is passed.
+ *
+ * Path support: converts \ to / and checks the file exists, if vfspath is true.
  * Returns string_null if the entity does not have the field, or the file is not in the VFS.
  *
  * FIXME: entities with //comments are not supported.
  */
+string GetField_fullspawndata(entity e, string fieldname, bool vfspath)
 {
        string v = string_null;
 
-       if (!e.fullspawndata)
-       {
-               //LOG_WARNF("^1EDICT %s (classname %s) has no fullspawndata, engine lacks support?", ftos(num_for_edict(e)), e.classname);
+       if (!e.fullspawndata) // Engine lacks support, warning spam in CheckEngineExtensions()
                return v;
-       }
 
        if (strstrofs(e.fullspawndata, "//", 0) >= 0)
        {
@@ -457,14 +462,14 @@ string GetField_fullspawndata(entity e, string f, ...)
                return v;
        }
 
-       //print(sprintf("%s(EDICT %s, FIELD %s)\n", __FUNC__, ftos(num_for_edict(e)), f));
+       //print(sprintf("%s(EDICT %s, FIELD %s)\n", __FUNC__, ftos(num_for_edict(e)), fieldname));
        //print(strcat("FULLSPAWNDATA:", e.fullspawndata, "\n"));
 
        // tokenize treats \ as an escape, but tokenize_console returns the required literal
        for (int t = tokenize_console(e.fullspawndata) - 3; t > 0; t -= 2)
        {
                //print(sprintf("\tTOKEN %s:%s\t%s:%s\n", ftos(t), ftos(t + 1), argv(t), argv(t + 1)));
-               if (argv(t) == f)
+               if (argv(t) == fieldname)
                {
                        v = argv(t + 1);
                        break;
@@ -473,7 +478,7 @@ string GetField_fullspawndata(entity e, string f, ...)
 
        //print(strcat("RESULT: ", v, "\n\n"));
 
-       if (v && ...(0, bool) == true)
+       if (v && vfspath)
        {
                v = strreplace("\\", "/", v);
                if (whichpack(v) == "")
@@ -483,6 +488,32 @@ string GetField_fullspawndata(entity e, string f, ...)
        return v;
 }
 
+/*
+=============
+FindFileInMapPack
+
+Returns the first matching VFS file path that exists in the current map's pack.
+Returns string_null if no files match or the map isn't packaged.
+=============
+*/
+string FindFileInMapPack(string pattern)
+{
+       if (!checkextension("DP_QC_FS_SEARCH_PACKFILE"))
+               return string_null;
+
+       string base_pack = whichpack(strcat("maps/", mapname, ".bsp"));
+       if (base_pack == "" || !base_pack) // this map isn't packaged or there was an error
+               return string_null;
+
+       int glob = search_packfile_begin(pattern, true, true, base_pack);
+       if (glob < 0)
+               return string_null;
+
+       string file = search_getfilename(glob, 0);
+       search_end(glob);
+       return file;
+}
+
 void WarpZone_PostInitialize_Callback()
 {
        // create waypoint links for warpzones