Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
spawnfunc.qh
Go to the documentation of this file.
1#pragma once
2
3// remove this ifdef when client or menu will actually make use of this stuff
4#ifdef SVQC
5
10noref string __fullspawndata;
12
13// Optional type checking; increases compile time too much to be enabled by default
14#if 0
15 bool entityfieldassignablefromeditor(int i)
16 {
17 switch (entityfieldtype(i))
18 {
19 case FIELD_STRING:
20 case FIELD_FLOAT:
21 case FIELD_VECTOR:
22 return true;
23 }
24 return false;
25 }
26
27 #define _spawnfunc_checktypes(fld) \
28 if (s == #fld) \
29 if (!entityfieldassignablefromeditor(i)) LOG_FATALF("Entity field '%s' cannot be whitelisted", s);
30#else
31 #define _spawnfunc_checktypes(fld)
32#endif
33 #define _spawnfunc_check(fld) \
34 if (s == #fld) continue;
35
39
40 .void(entity) __spawnfunc_constructor;
42
43 #define SPAWNFUNC_INTERNAL_FIELDS(X) \
44 X(string, classname, "spawnfunc") \
45 X(string, target, string_null) \
46 X(string, target2, string_null) \
47 X(string, target3, string_null) \
48 X(string, target4, string_null) \
49 X(string, targetname, string_null) \
50 /**/
51
52 #define X(T, fld, def) .T fld, __spawnfunc_##fld;
54 #undef X
55
56 void __spawnfunc_defer(entity prototype, void(entity) constructor)
57 {
58 IL_PUSH(g_spawn_queue, prototype);
59 #define X(T, fld, def) { prototype.__spawnfunc_##fld = prototype.fld; prototype.fld = def; }
61 #undef X
62 prototype.__spawnfunc_constructor = constructor;
63 }
64
66 #define __spawnfunc_spawn_all() MACRO_BEGIN \
67 g_map_entities = IL_NEW(); \
68 IL_EACH(g_spawn_queue, true, __spawnfunc_spawn(it)); \
69 MACRO_END
70#ifdef SVQC
72#endif
73 void __spawnfunc_spawn(entity prototype)
74 {
75 entity e = new(clone);
76 copyentity_qc(prototype, e);
78 #define X(T, fld, def) { e.fld = e.__spawnfunc_##fld; e.__spawnfunc_##fld = def; }
80 #undef X
81#ifdef SVQC
83 if (wasfreed(e)) {
84 return;
85 }
86#endif
87 e.__spawnfunc_constructor(e);
88 }
89
90// this function simply avoids expanding IL_NEW during compilation
91// for each spawning entity
93
95
96#define spawnfunc(id) \
97 void __spawnfunc_##id(entity this); \
98 ACCUMULATE void spawnfunc_##id(entity this) \
99 { \
100 if (!__spawnfunc_first) { \
101 __spawnfunc_first = true; \
102 static_init_early(); \
103 } \
104 bool dospawn = true; \
105 if (__spawnfunc_expecting > 1) { __spawnfunc_expecting = 0; } \
106 else if (__spawnfunc_expecting) { \
107 /* engine call */ \
108 if (!g_spawn_queue) g_spawn_queue_spawn(); \
109 __spawnfunc_expecting = 0; \
110 this = __spawnfunc_expect; \
111 __spawnfunc_expect = NULL; \
112 dospawn = false; \
113 } else { \
114 /* userland call */ \
115 assert(this); \
116 } \
117 if (!this.sourceLoc) { \
118 this.sourceLoc = __FILE__":"STR(__LINE__); \
119 } \
120 this.classname = #id; \
121 if (!this.spawnfunc_checked) { \
122 if (__fullspawndata) { \
123 /* not supported in old DP */ \
124 /* must be read inside the real spawnfunc */ \
125 this.fullspawndata = __fullspawndata; \
126 } \
127 this.spawnfunc_checked = true; \
128 if (this) { \
129 /* not worldspawn, delay spawn */ \
130 /* clear some dangerous fields (TODO: properly support these in the map!) */ \
131 this.think = func_null; \
132 this.nextthink = 0; \
133 __spawnfunc_defer(this, __spawnfunc_##id); \
134 } else { \
135 /* world might not be "worldspawn" */ \
136 this.__spawnfunc_constructor = __spawnfunc_##id; \
137 } \
138 } \
139 if (dospawn) { __spawnfunc_##id(this); } \
140 if (__spawnfunc_unreachable_workaround) return; \
141 } \
142 void __spawnfunc_##id(entity this)
143
144#endif
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
limitations: NULL cannot be present elements can only be present once a maximum of IL_MAX lists can e...
float FIELD_VECTOR
float FIELD_STRING
float FIELD_FLOAT
#define X()
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define IL_NEW()
void copyentity_qc(entity src, entity dst)
Definition oo.qh:86
noref IntrusiveList g_map_entities
Definition spawnfunc.qh:65
void g_spawn_queue_spawn()
Definition spawnfunc.qh:92
#define SPAWNFUNC_INTERNAL_FIELDS(X)
Definition spawnfunc.qh:43
noref bool __spawnfunc_first
Definition spawnfunc.qh:94
noref string __fullspawndata
Not for production use, provides access to a dump of the entity's fields when it is parsed from map d...
Definition spawnfunc.qh:10
void __spawnfunc_spawn(entity prototype)
Definition spawnfunc.qh:73
noref bool __spawnfunc_unreachable_workaround
Definition spawnfunc.qh:38
void _SV_OnEntityPreSpawnFunction(entity this)
void __spawnfunc_defer(entity prototype, void(entity) constructor)
Definition spawnfunc.qh:56
noref entity __spawnfunc_expect
Definition spawnfunc.qh:37
noref bool require_spawnfunc_prefix
If this global exists, only functions with spawnfunc_ name prefix qualify as spawn functions.
Definition spawnfunc.qh:7
string fullspawndata
Definition spawnfunc.qh:11
bool spawnfunc_checked
Definition spawnfunc.qh:8
noref IntrusiveList g_spawn_queue
Definition spawnfunc.qh:41
noref int __spawnfunc_expecting
Definition spawnfunc.qh:36