From: bones_was_here Date: Sat, 18 May 2024 11:38:05 +0000 (+1000) Subject: Fix GetField_fullspawndata sometimes taking the wrong code path X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=040c1c11fdb09f5721f51e9982834d13ac5f19d9;p=xonotic%2Fxonotic-data.pk3dir.git Fix GetField_fullspawndata sometimes taking the wrong code path 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 --- diff --git a/qcsrc/common/mapinfo.qc b/qcsrc/common/mapinfo.qc index c1cdd7a90..707c6826c 100644 --- a/qcsrc/common/mapinfo.qc +++ b/qcsrc/common/mapinfo.qc @@ -1339,7 +1339,7 @@ LABEL(mapinfo_handled) if (world.message != "") MapInfo_Map_title = world.message; if (MapInfo_Map_author == "") - if ((s = GetField_fullspawndata(world, "author")) != "") + if ((s = GetField_fullspawndata(world, "author", false)) != "") MapInfo_Map_author = s; } #endif diff --git a/qcsrc/common/mapobjects/func/door.qc b/qcsrc/common/mapobjects/func/door.qc index 30909e4c4..1e8cb985f 100644 --- a/qcsrc/common/mapobjects/func/door.qc +++ b/qcsrc/common/mapobjects/func/door.qc @@ -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); } diff --git a/qcsrc/common/mapobjects/target/speed.qc b/qcsrc/common/mapobjects/target/speed.qc index 4c3618cad..83f25495f 100644 --- a/qcsrc/common/mapobjects/target/speed.qc +++ b/qcsrc/common/mapobjects/target/speed.qc @@ -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; diff --git a/qcsrc/server/compat/quake3.qc b/qcsrc/server/compat/quake3.qc index a4c55116b..59c0ebd14 100644 --- a/qcsrc/server/compat/quake3.qc +++ b/qcsrc/server/compat/quake3.qc @@ -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; diff --git a/qcsrc/server/items/items.qc b/qcsrc/server/items/items.qc index 825f003a5..f43fa3b3d 100644 --- a/qcsrc/server/items/items.qc +++ b/qcsrc/server/items/items.qc @@ -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); } diff --git a/qcsrc/server/main.qc b/qcsrc/server/main.qc index 194808177..b0433b9ea 100644 --- a/qcsrc/server/main.qc +++ b/qcsrc/server/main.qc @@ -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) == "") diff --git a/qcsrc/server/main.qh b/qcsrc/server/main.qh index 30b686471..8fa9b357e 100644 --- a/qcsrc/server/main.qh +++ b/qcsrc/server/main.qh @@ -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); /* ==================