]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Add function to access "raw" map entity field values in engines with __fullspawndata...
authorbones_was_here <bones_was_here@xa.org.au>
Wed, 9 Sep 2020 17:34:46 +0000 (03:34 +1000)
committerbones_was_here <bones_was_here@xa.org.au>
Wed, 9 Sep 2020 17:34:46 +0000 (03:34 +1000)
qcsrc/lib/spawnfunc.qh
qcsrc/server/miscfunctions.qc

index 7130703ec8e4783e3878c013c109c00f7d63279e..bed384ec69697b1bbf6f0df42b84fc2db2f94f9d 100644 (file)
@@ -7,6 +7,8 @@
 noref bool require_spawnfunc_prefix;
 .bool spawnfunc_checked;
 
+.string fullspawndata;
+
 // Optional type checking; increases compile time too much to be enabled by default
 #if 0
        bool entityfieldassignablefromeditor(int i)
@@ -282,6 +284,11 @@ noref bool __spawnfunc_first;
                } \
                if (!this.spawnfunc_checked) { \
                        _checkWhitelisted(this, #id); \
+                       if (__fullspawndata) { \
+                               /* not supported in old DP */ \
+                               /* must be read inside the real spawnfunc */ \
+                               this.fullspawndata = __fullspawndata; \
+                       } \
                        this.spawnfunc_checked = true; \
                        if (this) { \
                                /* not worldspawn, delay spawn */ \
index e8b4ab681c5bb91a64e7ef650dd89c2dfd3018cd..c74637c07e6b5f886f5fa8dd3b7af8fbc16ee9cc 100644 (file)
@@ -1446,3 +1446,59 @@ bool isPushable(entity e)
                return true;
        return false;
 }
+
+string GetField_fullspawndata(entity e, string f, ...)
+/* 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.
+ * 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 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);
+               return v;
+       }
+
+       if (strstrofs(e.fullspawndata, "//", 0) >= 0)
+       {
+               // tokenize and tokenize_console return early if "//" is reached,
+               // which can leave an odd number of tokens and break key:value pairing.
+               LOG_WARNF("^1EDICT %s fullspawndata contains unsupported //comment^7%s", ftos(num_for_edict(e)), e.fullspawndata);
+               return v;
+       }
+
+       //print(sprintf("%s(EDICT %s, FIELD %s)\n", __FUNC__, ftos(num_for_edict(e)), f));
+       //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)
+               {
+                       v = argv(t + 1);
+                       break;
+               }
+       }
+
+       //print(strcat("RESULT: ", v, "\n\n"));
+
+       if (v && ...(0, bool) == true)
+       {
+               v = strreplace("\\", "/", v);
+               if (whichpack(v) == "")
+                       return string_null;
+       }
+
+       return v;
+}