]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/spawnfunc.qh
Merge branch 'master' into terencehill/menu_optimization
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / spawnfunc.qh
1 #ifndef SPAWNFUNC_H
2 #define SPAWNFUNC_H
3
4 /** If this global exists, only functions with spawnfunc_ name prefix qualify as spawn functions */
5 noref bool require_spawnfunc_prefix;
6 .bool spawnfunc_checked;
7
8 // Optional type checking; increases compile time too much to be enabled by default
9 #if 0
10         bool entityfieldassignablefromeditor(int i)
11         {
12                 switch (entityfieldtype(i))
13                 {
14                         case FIELD_STRING:
15                         case FIELD_FLOAT:
16                         case FIELD_VECTOR:
17                                 return true;
18                 }
19                 return false;
20         }
21
22         #define _spawnfunc_checktypes(fld) \
23                 if (fieldname == #fld) \
24                         if (!entityfieldassignablefromeditor(i)) LOG_FATALF("Entity field '%s' cannot be whitelisted\n", fieldname);
25 #else
26         #define _spawnfunc_checktypes(fld)
27 #endif
28         #define _spawnfunc_check(fld) \
29                 if (fieldname == #fld) continue;
30
31         noref entity __spawnfunc_expect;
32         bool __spawnfunc_unreachable_workaround = true;
33
34         #define spawnfunc_1(id) spawnfunc_2(id, FIELDS_UNION)
35         #define spawnfunc_2(id, whitelist) \
36                 void __spawnfunc_##id(entity this); \
37                 [[accumulate]] void spawnfunc_##id(entity this) \
38                 { \
39                         if (self == __spawnfunc_expect) \
40                         { \
41                                 /* engine call */ \
42                                 __spawnfunc_expect = NULL; \
43                                 this = self; \
44                         } \
45                         else \
46                         { \
47                                 assert(this); \
48                         } \
49                         if (!this.sourceLocFile) \
50                         { \
51                                 this.sourceLocFile = __FILE__; \
52                                 this.sourceLocLine = __LINE__; \
53                         } \
54                         if (!this.spawnfunc_checked) \
55                         { \
56                                 for (int i = 0, n = numentityfields(); i < n; ++i) \
57                                 { \
58                                         string value = getentityfieldstring(i, this); \
59                                         string fieldname = entityfieldname(i); \
60                                         whitelist(_spawnfunc_checktypes) \
61                                         if (value == "") continue; \
62                                         if (fieldname == "") continue; \
63                                         FIELDS_COMMON(_spawnfunc_check) \
64                                         whitelist(_spawnfunc_check) \
65                                         LOG_WARNINGF(_("Entity field %s.%s (%s) is not whitelisted. If you believe this is an error, please file an issue.\n"), #id, fieldname, value); \
66                                 } \
67                                 this.spawnfunc_checked = true; \
68                         } \
69                         __spawnfunc_##id(this); \
70                         if (__spawnfunc_unreachable_workaround) return; \
71                 } \
72                 void __spawnfunc_##id(entity this)
73
74         #define FIELD_SCALAR(fld, n) \
75                 fld(n)
76         #define FIELD_VEC(fld, n) \
77                 fld(n) \
78                 fld(n##_x) \
79                 fld(n##_y) \
80                 fld(n##_z)
81
82         #define FIELDS_NONE(fld)
83         #define FIELDS_ALL(fld) if (false)
84
85         #define FIELDS_COMMON(fld) \
86                 FIELD_SCALAR(fld, classname) \
87                 FIELD_SCALAR(fld, spawnfunc_checked) \
88                 /**/
89
90         #define FIELDS_UNION(fld) \
91                 FIELD_SCALAR(fld, sourceLocFile) \
92                 FIELD_SCALAR(fld, sourceLocLine) \
93                 FIELD_SCALAR(fld, Version) \
94                 FIELD_SCALAR(fld, ammo_cells) \
95                 FIELD_SCALAR(fld, ammo_nails) \
96                 FIELD_SCALAR(fld, ammo_rockets) \
97                 FIELD_SCALAR(fld, armorvalue) \
98                 FIELD_SCALAR(fld, atten) \
99                 FIELD_SCALAR(fld, bgmscriptdecay) \
100                 FIELD_SCALAR(fld, bgmscriptsustain) \
101                 FIELD_SCALAR(fld, bgmscript) \
102                 FIELD_SCALAR(fld, button0) \
103                 FIELD_SCALAR(fld, cnt) \
104                 FIELD_SCALAR(fld, colormap) \
105                 FIELD_SCALAR(fld, count) \
106                 FIELD_SCALAR(fld, curvetarget) \
107                 FIELD_SCALAR(fld, cvarfilter) \
108                 FIELD_SCALAR(fld, debrisdamageforcescale) \
109                 FIELD_SCALAR(fld, debrisfadetime) \
110                 FIELD_SCALAR(fld, debristimejitter) \
111                 FIELD_SCALAR(fld, debristime) \
112                 FIELD_SCALAR(fld, debris) \
113                 FIELD_SCALAR(fld, delay) \
114                 FIELD_SCALAR(fld, dmgtime) \
115                 FIELD_SCALAR(fld, dmg) \
116                 FIELD_SCALAR(fld, dmg_edge) \
117                 FIELD_SCALAR(fld, dmg_force) \
118                 FIELD_SCALAR(fld, dmg_radius) \
119                 FIELD_SCALAR(fld, effects) \
120                 FIELD_SCALAR(fld, flags) \
121                 FIELD_SCALAR(fld, fog) \
122                 FIELD_SCALAR(fld, frags) \
123                 FIELD_SCALAR(fld, frame) \
124                 FIELD_SCALAR(fld, gametypefilter) \
125                 FIELD_SCALAR(fld, geomtype) \
126                 FIELD_SCALAR(fld, gravity) \
127                 FIELD_SCALAR(fld, health) \
128                 FIELD_SCALAR(fld, height) \
129                 FIELD_SCALAR(fld, impulse) \
130                 FIELD_SCALAR(fld, killtarget) \
131                 FIELD_SCALAR(fld, lerpfrac) \
132                 FIELD_SCALAR(fld, light_lev) \
133                 FIELD_SCALAR(fld, lip) \
134                 FIELD_SCALAR(fld, loddistance1) \
135                 FIELD_SCALAR(fld, lodmodel1) \
136                 FIELD_SCALAR(fld, ltime) \
137                 FIELD_SCALAR(fld, mdl) \
138                 FIELD_SCALAR(fld, message2) \
139                 FIELD_SCALAR(fld, message) \
140                 FIELD_SCALAR(fld, modelindex) \
141                 FIELD_SCALAR(fld, modelscale) \
142                 FIELD_SCALAR(fld, model) \
143                 FIELD_SCALAR(fld, monster_moveflags) \
144                 FIELD_SCALAR(fld, movetype) \
145                 FIELD_SCALAR(fld, netname) \
146                 FIELD_SCALAR(fld, nextthink) \
147                 FIELD_SCALAR(fld, noalign) \
148                 FIELD_SCALAR(fld, noise1) \
149                 FIELD_SCALAR(fld, noise2) \
150                 FIELD_SCALAR(fld, noise) \
151                 FIELD_SCALAR(fld, phase) \
152                 FIELD_SCALAR(fld, platmovetype) \
153                 FIELD_SCALAR(fld, race_place) \
154                 FIELD_SCALAR(fld, radius) \
155                 FIELD_SCALAR(fld, respawntimejitter) \
156                 FIELD_SCALAR(fld, respawntime) \
157                 FIELD_SCALAR(fld, restriction) \
158                 FIELD_SCALAR(fld, scale) \
159                 FIELD_SCALAR(fld, skin) \
160                 FIELD_SCALAR(fld, solid) \
161                 FIELD_SCALAR(fld, sound1) \
162                 FIELD_SCALAR(fld, sounds) \
163                 FIELD_SCALAR(fld, spawnflags) \
164                 FIELD_SCALAR(fld, speed) \
165                 FIELD_SCALAR(fld, strength) \
166                 FIELD_SCALAR(fld, target2) \
167                 FIELD_SCALAR(fld, target3) \
168                 FIELD_SCALAR(fld, target4) \
169                 FIELD_SCALAR(fld, targetname) \
170                 FIELD_SCALAR(fld, target) \
171                 FIELD_SCALAR(fld, target_random) \
172                 FIELD_SCALAR(fld, target_range) \
173                 FIELD_SCALAR(fld, team) \
174                 FIELD_SCALAR(fld, turret_scale_health) \
175                 FIELD_SCALAR(fld, turret_scale_range) \
176                 FIELD_SCALAR(fld, turret_scale_respawn) \
177                 FIELD_SCALAR(fld, volume) \
178                 FIELD_SCALAR(fld, wait) \
179                 FIELD_SCALAR(fld, warpzone_fadeend) \
180                 FIELD_SCALAR(fld, warpzone_fadestart) \
181                 FIELD_SCALAR(fld, weapon) \
182                 FIELD_VEC(fld, absmax) \
183                 FIELD_VEC(fld, absmin) \
184                 FIELD_VEC(fld, angles) \
185                 FIELD_VEC(fld, avelocity) \
186                 FIELD_VEC(fld, maxs) \
187                 FIELD_VEC(fld, maxs) \
188                 FIELD_VEC(fld, mins) \
189                 FIELD_VEC(fld, modelscale_vec) \
190                 FIELD_VEC(fld, origin) \
191                 FIELD_VEC(fld, velocity) \
192                 /**/
193
194         #define spawnfunc(...) EVAL(OVERLOAD(spawnfunc, __VA_ARGS__))
195
196 #endif