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;
8 // Optional type checking; increases compile time too much to be enabled by default
10 bool entityfieldassignablefromeditor(int i)
12 switch (entityfieldtype(i))
22 #define _spawnfunc_checktypes(fld) \
23 if (fieldname == #fld) \
24 if (!entityfieldassignablefromeditor(i)) LOG_FATALF("Entity field '%s' cannot be whitelisted\n", fieldname);
26 #define _spawnfunc_checktypes(fld)
28 #define _spawnfunc_check(fld) \
29 if (fieldname == #fld) continue;
31 bool __spawnfunc_unreachable_workaround = true;
33 #define spawnfunc_1(id) spawnfunc_2(id, FIELDS_UNION)
34 #define spawnfunc_2(id, whitelist) \
35 void __spawnfunc_##id(entity this); \
36 [[accumulate]] void spawnfunc_##id(entity this) \
39 if (!this.sourceLocFile) \
41 this.sourceLocFile = __FILE__; \
42 this.sourceLocLine = __LINE__; \
44 if (!this.spawnfunc_checked) \
46 for (int i = 0, n = numentityfields(); i < n; ++i) \
48 string value = getentityfieldstring(i, this); \
49 string fieldname = entityfieldname(i); \
50 whitelist(_spawnfunc_checktypes) \
51 if (value == "") continue; \
52 if (fieldname == "") continue; \
53 FIELDS_COMMON(_spawnfunc_check) \
54 whitelist(_spawnfunc_check) \
55 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); \
57 this.spawnfunc_checked = true; \
59 __spawnfunc_##id(this); \
60 if (__spawnfunc_unreachable_workaround) return; \
62 void __spawnfunc_##id(entity this)
64 #define FIELD_SCALAR(fld, n) \
66 #define FIELD_VEC(fld, n) \
72 #define FIELDS_NONE(fld)
73 #define FIELDS_ALL(fld) if (false)
75 #define FIELDS_COMMON(fld) \
76 FIELD_SCALAR(fld, classname) \
77 FIELD_SCALAR(fld, spawnfunc_checked) \
80 #define FIELDS_UNION(fld) \
81 FIELD_SCALAR(fld, sourceLocFile) \
82 FIELD_SCALAR(fld, sourceLocLine) \
83 FIELD_SCALAR(fld, Version) \
84 FIELD_SCALAR(fld, ammo_cells) \
85 FIELD_SCALAR(fld, ammo_nails) \
86 FIELD_SCALAR(fld, ammo_rockets) \
87 FIELD_SCALAR(fld, armorvalue) \
88 FIELD_SCALAR(fld, atten) \
89 FIELD_SCALAR(fld, bgmscriptdecay) \
90 FIELD_SCALAR(fld, bgmscriptsustain) \
91 FIELD_SCALAR(fld, bgmscript) \
92 FIELD_SCALAR(fld, button0) \
93 FIELD_SCALAR(fld, cnt) \
94 FIELD_SCALAR(fld, colormap) \
95 FIELD_SCALAR(fld, count) \
96 FIELD_SCALAR(fld, curvetarget) \
97 FIELD_SCALAR(fld, cvarfilter) \
98 FIELD_SCALAR(fld, debrisdamageforcescale) \
99 FIELD_SCALAR(fld, debrisfadetime) \
100 FIELD_SCALAR(fld, debristimejitter) \
101 FIELD_SCALAR(fld, debristime) \
102 FIELD_SCALAR(fld, debris) \
103 FIELD_SCALAR(fld, delay) \
104 FIELD_SCALAR(fld, dmgtime) \
105 FIELD_SCALAR(fld, dmg) \
106 FIELD_SCALAR(fld, dmg_edge) \
107 FIELD_SCALAR(fld, dmg_force) \
108 FIELD_SCALAR(fld, dmg_radius) \
109 FIELD_SCALAR(fld, effects) \
110 FIELD_SCALAR(fld, flags) \
111 FIELD_SCALAR(fld, fog) \
112 FIELD_SCALAR(fld, frags) \
113 FIELD_SCALAR(fld, frame) \
114 FIELD_SCALAR(fld, gametypefilter) \
115 FIELD_SCALAR(fld, geomtype) \
116 FIELD_SCALAR(fld, gravity) \
117 FIELD_SCALAR(fld, health) \
118 FIELD_SCALAR(fld, height) \
119 FIELD_SCALAR(fld, impulse) \
120 FIELD_SCALAR(fld, killtarget) \
121 FIELD_SCALAR(fld, lerpfrac) \
122 FIELD_SCALAR(fld, light_lev) \
123 FIELD_SCALAR(fld, lip) \
124 FIELD_SCALAR(fld, loddistance1) \
125 FIELD_SCALAR(fld, lodmodel1) \
126 FIELD_SCALAR(fld, ltime) \
127 FIELD_SCALAR(fld, mdl) \
128 FIELD_SCALAR(fld, message2) \
129 FIELD_SCALAR(fld, message) \
130 FIELD_SCALAR(fld, modelindex) \
131 FIELD_SCALAR(fld, modelscale) \
132 FIELD_SCALAR(fld, model) \
133 FIELD_SCALAR(fld, monster_moveflags) \
134 FIELD_SCALAR(fld, movetype) \
135 FIELD_SCALAR(fld, netname) \
136 FIELD_SCALAR(fld, nextthink) \
137 FIELD_SCALAR(fld, noalign) \
138 FIELD_SCALAR(fld, noise1) \
139 FIELD_SCALAR(fld, noise2) \
140 FIELD_SCALAR(fld, noise) \
141 FIELD_SCALAR(fld, ok_item) \
142 FIELD_SCALAR(fld, phase) \
143 FIELD_SCALAR(fld, platmovetype) \
144 FIELD_SCALAR(fld, pickup_anyway) \
145 FIELD_SCALAR(fld, race_place) \
146 FIELD_SCALAR(fld, radius) \
147 FIELD_SCALAR(fld, respawntimejitter) \
148 FIELD_SCALAR(fld, respawntime) \
149 FIELD_SCALAR(fld, restriction) \
150 FIELD_SCALAR(fld, scale) \
151 FIELD_SCALAR(fld, skin) \
152 FIELD_SCALAR(fld, solid) \
153 FIELD_SCALAR(fld, sound1) \
154 FIELD_SCALAR(fld, sounds) \
155 FIELD_SCALAR(fld, spawnflags) \
156 FIELD_SCALAR(fld, speed) \
157 FIELD_SCALAR(fld, strength) \
158 FIELD_SCALAR(fld, target2) \
159 FIELD_SCALAR(fld, target3) \
160 FIELD_SCALAR(fld, target4) \
161 FIELD_SCALAR(fld, targetname) \
162 FIELD_SCALAR(fld, target) \
163 FIELD_SCALAR(fld, target_random) \
164 FIELD_SCALAR(fld, target_range) \
165 FIELD_SCALAR(fld, team) \
166 FIELD_SCALAR(fld, turret_scale_health) \
167 FIELD_SCALAR(fld, turret_scale_range) \
168 FIELD_SCALAR(fld, turret_scale_respawn) \
169 FIELD_SCALAR(fld, volume) \
170 FIELD_SCALAR(fld, wait) \
171 FIELD_SCALAR(fld, warpzone_fadeend) \
172 FIELD_SCALAR(fld, warpzone_fadestart) \
173 FIELD_SCALAR(fld, weapon) \
174 FIELD_VEC(fld, absmax) \
175 FIELD_VEC(fld, absmin) \
176 FIELD_VEC(fld, angles) \
177 FIELD_VEC(fld, avelocity) \
178 FIELD_VEC(fld, maxs) \
179 FIELD_VEC(fld, maxs) \
180 FIELD_VEC(fld, mins) \
181 FIELD_VEC(fld, modelscale_vec) \
182 FIELD_VEC(fld, origin) \
183 FIELD_VEC(fld, velocity) \
186 #define spawnfunc(...) EVAL(OVERLOAD(spawnfunc, __VA_ARGS__))