]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Fix GetField_fullspawndata sometimes taking the wrong code path
authorbones_was_here <bones_was_here@xonotic.au>
Sat, 18 May 2024 11:38:05 +0000 (21:38 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Mon, 27 May 2024 09:23:20 +0000 (19:23 +1000)
When the optional parameter wasn't passed, uninitialised data was read,
which caused door linking to fail on some Q3 maps.

Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
qcsrc/common/mapinfo.qc
qcsrc/common/mapobjects/func/door.qc
qcsrc/common/mapobjects/target/speed.qc
qcsrc/server/compat/quake3.qc
qcsrc/server/items/items.qc
qcsrc/server/main.qc
qcsrc/server/main.qh

index c1cdd7a90cd0b22d4dd940931caf2f6f1d7c485e..707c6826ceb555270e865a99fcdd1f24171cc388 100644 (file)
@@ -1339,7 +1339,7 @@ LABEL(mapinfo_handled)
                        if (world.message != "")
                                MapInfo_Map_title = world.message;
                if (MapInfo_Map_author == "<AUTHOR>")
-                       if ((s = GetField_fullspawndata(world, "author")) != "")
+                       if ((s = GetField_fullspawndata(world, "author", false)) != "")
                                MapInfo_Map_author = s;
        }
 #endif
index 30909e4c453cf03172dae866051677272b6d1e24..1e8cb985f2bd07f67d91d807c02431052a76e877 100644 (file)
@@ -809,7 +809,7 @@ spawnfunc(func_door)
 
                if (!this.team)
                {
-                       string t = GetField_fullspawndata(this, "team");
+                       string t = GetField_fullspawndata(this, "team", false);
                        // bones_was_here: same hack as used to support teamed items on Q3 maps
                        if (t) this.team = crc16(false, t);
                }
index 4c3618cad65911d97204d36d397f1cf077ecbbb8..83f25495f6b5dac240bb92071387a3fcf2a668af 100644 (file)
@@ -160,7 +160,7 @@ spawnfunc(target_speed)
        this.reset = target_speed_reset;
 
        // support a 0 speed setting AND a default
-       string s = GetField_fullspawndata(this, "speed");
+       string s = GetField_fullspawndata(this, "speed", false);
        if (!s || s == "")
                this.speed = 100;
 
index a4c55116bc02c7a7f95e556a9e1bda391a2a4e21..59c0ebd14581cf0d19dd824d482907ecc9233ecf 100644 (file)
@@ -346,29 +346,29 @@ bool DoesQ3ARemoveThisEntity(entity this)
        // Xonotic is usually played with a CPM-based physics so we default to CPM mode
        if(cvar_string("g_mod_physics") == "Q3")
        {
-               if(stof(GetField_fullspawndata(this, "notvq3")))
+               if(stof(GetField_fullspawndata(this, "notvq3", false)))
                        return true;
        }
-       else if(stof(GetField_fullspawndata(this, "notcpm")))
+       else if(stof(GetField_fullspawndata(this, "notcpm", false)))
                return true;
 
        // Q3 mappers use "notq3a" or "notta" to disable an entity in Q3A or Q3TA
        // Xonotic has ~equivalent features to Team Arena
-       if(stof(GetField_fullspawndata(this, "notta")))
+       if(stof(GetField_fullspawndata(this, "notta", false)))
                return true;
 
        // FIXME: singleplayer does not use maxclients 1 as that would prevent bots,
        // this is the case in Q3 also, it uses another method to block clients.
        // Only accessible in VQ3, via the `spmap` command.
-       if(stof(GetField_fullspawndata(this, "notsingle")))
+       if(stof(GetField_fullspawndata(this, "notsingle", false)))
                if(maxclients == 1 && IS_GAMETYPE(DEATHMATCH))
                        return true;
 
-       if(stof(GetField_fullspawndata(this, "notteam")))
+       if(stof(GetField_fullspawndata(this, "notteam", false)))
                if(teamplay)
                        return true;
 
-       if(stof(GetField_fullspawndata(this, "notfree")))
+       if(stof(GetField_fullspawndata(this, "notfree", false)))
                if(!teamplay)
                        return true;
 
index 825f003a5a0d249114bc7625e92b847d7b564445..f43fa3b3dc0cbc2d708f0a28bb541eaa26f8bc9e 100644 (file)
@@ -1104,7 +1104,7 @@ void StartItem(entity this, entity def)
                {
                        if (!this.team)
                        {
-                               string t = GetField_fullspawndata(this, "team");
+                               string t = GetField_fullspawndata(this, "team", false);
                                // bones_was_here: this hack is cheaper than changing to a .string strcmp()
                                if(t) this.team = crc16(false, t);
                        }
index 1948081779223775f9ea498bfb10f508402de86e..b0433b9ea5990b5131a759f544a63e404d2de8ca 100644 (file)
@@ -434,7 +434,7 @@ void SV_OnEntityPreSpawnFunction(entity this)
        }
 }
 
-/** 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.
  *
@@ -442,12 +442,12 @@ void SV_OnEntityPreSpawnFunction(entity this)
  *
  * 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 f, ...)
+string GetField_fullspawndata(entity e, string fieldname, bool vfspath)
 {
        string v = string_null;
 
@@ -462,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;
@@ -478,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) == "")
index 30b6864716063cdd5f62c31159ac2e3c71b5c575..8fa9b357e7c2ef8365c76b6456e61c688184bec6 100644 (file)
@@ -48,7 +48,7 @@ float servertime, serverprevtime, serverframetime;
 
 .float contents_damagetime;
 
-string GetField_fullspawndata(entity e, string f, ...);
+string GetField_fullspawndata(entity e, string fieldname, bool vfspath);
 
 /*
 ==================