]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
spawnfuncs: initial support for prototypical construction
authorTimePath <andrew.hardaker1995@gmail.com>
Wed, 30 Aug 2017 11:47:00 +0000 (21:47 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Fri, 1 Sep 2017 09:53:55 +0000 (19:53 +1000)
qcsrc/lib/spawnfunc.qh
qcsrc/server/g_world.qc

index 34b10830413af229cb45970d272d749858dd80bb..98922d4876194748d636ca5978abfff084a5ac4e 100644 (file)
@@ -31,8 +31,37 @@ noref bool require_spawnfunc_prefix;
        noref entity __spawnfunc_expect;
        noref bool __spawnfunc_unreachable_workaround = true;
 
-    .void(entity) __spawnfunc_spawn;
+    .void(entity) __spawnfunc_constructor;
     noref IntrusiveList g_spawn_queue;
+    .string targetname, __spawnfunc_targetname;
+    #define SPAWNFUNC_INTERNAL_FIELDS(X) \
+        X(targetname, string_null) \
+        /**/
+    void __spawnfunc_defer(entity prototype, void(entity) constructor)
+    {
+        IL_PUSH(g_spawn_queue, prototype);
+        #define X(fld, def) { prototype.__spawnfunc_##fld = prototype.fld; prototype.fld = def; }
+        SPAWNFUNC_INTERNAL_FIELDS(X);
+        #undef X
+        prototype.__spawnfunc_constructor = constructor;
+    }
+
+    noref IntrusiveList g_map_entities;
+    #define __spawnfunc_spawn_all() MACRO_BEGIN \
+        g_map_entities = IL_NEW(); \
+        IL_EACH(g_spawn_queue, true, __spawnfunc_spawn(it)); \
+    MACRO_END
+
+    void __spawnfunc_spawn(entity prototype)
+    {
+        entity e = new(clone);
+        copyentity(prototype, e);
+        IL_PUSH(g_map_entities, e);
+        #define X(fld, def) { e.fld = e.__spawnfunc_##fld; e.__spawnfunc_##fld = def; }
+        SPAWNFUNC_INTERNAL_FIELDS(X);
+        #undef X
+        e.__spawnfunc_constructor(e);
+    }
 
        #define spawnfunc_1(id) spawnfunc_2(id, FIELDS_UNION)
        #define spawnfunc_2(id, whitelist) \
@@ -69,8 +98,7 @@ noref bool require_spawnfunc_prefix;
                                this.spawnfunc_checked = true; \
                                if (this) { \
                     /* not worldspawn, delay spawn */ \
-                    this.__spawnfunc_spawn = spawnfunc_##id; \
-                    IL_PUSH(g_spawn_queue, this); \
+                    __spawnfunc_defer(this, __spawnfunc_##id); \
                 } \
                        } \
                        if (dospawn) { __spawnfunc_##id(this); } \
index 1b8685a62908805cb187201382c022ad6d7b2bf2..c47952c5d99f0c83231c5916c6f47e0fcfb13183 100644 (file)
@@ -936,10 +936,7 @@ spawnfunc(worldspawn)
        WinningConditionHelper(this); // set worldstatus
 
        world_initialized = 1;
-
-       IL_EACH(g_spawn_queue, true, {
-        it.__spawnfunc_spawn(it);
-    });
+       __spawnfunc_spawn_all();
 }
 
 spawnfunc(light)