7 noref
bool require_spawnfunc_prefix;
8 .bool spawnfunc_checked;
10 noref
string __fullspawndata;
11 .string fullspawndata;
15 bool entityfieldassignablefromeditor(
int i)
17 switch (entityfieldtype(i))
27 #define _spawnfunc_checktypes(fld) \ 29 if (!entityfieldassignablefromeditor(i)) LOG_FATALF("Entity field '%s' cannot be whitelisted", s); 31 #define _spawnfunc_checktypes(fld) 33 #define _spawnfunc_check(fld) \ 34 if (s == #fld) continue; 36 noref
int __spawnfunc_expecting;
37 noref
entity __spawnfunc_expect;
38 noref
bool __spawnfunc_unreachable_workaround =
true;
40 .void(
entity) __spawnfunc_constructor;
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) \ 52 #define X(T, fld, def) .T fld, __spawnfunc_##fld; 53 SPAWNFUNC_INTERNAL_FIELDS(
X)
56 void __spawnfunc_defer(
entity prototype,
void(
entity) constructor)
58 IL_PUSH(g_spawn_queue, prototype);
59 #define X(T, fld, def) { prototype.__spawnfunc_##fld = prototype.fld; prototype.fld = def; } 60 SPAWNFUNC_INTERNAL_FIELDS(
X);
62 prototype.__spawnfunc_constructor = constructor;
66 #define __spawnfunc_spawn_all() MACRO_BEGIN \ 67 g_map_entities = IL_NEW(); \ 68 IL_EACH(g_spawn_queue, true, __spawnfunc_spawn(it)); \ 71 void _SV_OnEntityPreSpawnFunction(
entity this);
73 void __spawnfunc_spawn(
entity prototype)
78 #define X(T, fld, def) { e.fld = e.__spawnfunc_##fld; e.__spawnfunc_##fld = def; } 79 SPAWNFUNC_INTERNAL_FIELDS(
X);
82 _SV_OnEntityPreSpawnFunction(e);
87 e.__spawnfunc_constructor(e);
90 #define FIELD_SCALAR(fld, n) \ 92 #define FIELD_VEC(fld, n) \ 98 #define FIELDS_NONE(fld) 99 #define FIELDS_ALL(fld) if (false) 101 #define FIELDS_COMMON(fld) \ 102 FIELD_SCALAR(fld, classname) \ 103 FIELD_SCALAR(fld, sourceLoc) \ 104 FIELD_SCALAR(fld, spawnfunc_checked) \ 105 FIELD_VEC(fld, origin) \ 108 #define FIELDS_UNION(fld) \ 109 FIELD_SCALAR(fld, Version) \ 110 FIELD_SCALAR(fld, ammo_cells) \ 111 FIELD_SCALAR(fld, ammo_nails) \ 112 FIELD_SCALAR(fld, ammo_rockets) \ 113 FIELD_SCALAR(fld, antiwall_flag) \ 114 FIELD_SCALAR(fld, armorvalue) \ 115 FIELD_SCALAR(fld, atten) \ 116 FIELD_SCALAR(fld, bgmscriptdecay) \ 117 FIELD_SCALAR(fld, bgmscriptsustain) \ 118 FIELD_SCALAR(fld, bgmscript) \ 119 FIELD_SCALAR(fld, button0) \ 120 FIELD_SCALAR(fld, chmap) \ 121 FIELD_SCALAR(fld, cnt) \ 122 FIELD_SCALAR(fld, colormap) \ 123 FIELD_SCALAR(fld, count) \ 124 FIELD_SCALAR(fld, curvetarget) \ 125 FIELD_SCALAR(fld, cvarfilter) \ 126 FIELD_SCALAR(fld, debrisdamageforcescale) \ 127 FIELD_SCALAR(fld, debrisfadetime) \ 128 FIELD_SCALAR(fld, debrismovetype) \ 129 FIELD_SCALAR(fld, debrisskin) \ 130 FIELD_SCALAR(fld, debristimejitter) \ 131 FIELD_SCALAR(fld, debristime) \ 132 FIELD_SCALAR(fld, debris) \ 133 FIELD_SCALAR(fld, delay) \ 134 FIELD_SCALAR(fld, dmgtime) \ 135 FIELD_SCALAR(fld, dmg) \ 136 FIELD_SCALAR(fld, dmg_edge) \ 137 FIELD_SCALAR(fld, dmg_force) \ 138 FIELD_SCALAR(fld, dmg_radius) \ 139 FIELD_SCALAR(fld, effects) \ 140 FIELD_SCALAR(fld, falloff) \ 141 FIELD_SCALAR(fld, flags) \ 142 FIELD_SCALAR(fld, fog) \ 143 FIELD_SCALAR(fld, frags) \ 144 FIELD_SCALAR(fld, frame) \ 145 FIELD_SCALAR(fld, gametype) \ 146 FIELD_SCALAR(fld, gametypefilter) \ 147 FIELD_SCALAR(fld, geomtype) \ 148 FIELD_SCALAR(fld, gravity) \ 149 FIELD_SCALAR(fld, health) \ 150 FIELD_SCALAR(fld, height) \ 151 FIELD_SCALAR(fld, impulse) \ 152 FIELD_SCALAR(fld, invincible_finished) \ 153 FIELD_SCALAR(fld, invisibility_finished) \ 154 FIELD_SCALAR(fld, item_pickupsound) \ 155 FIELD_SCALAR(fld, killtarget) \ 156 FIELD_SCALAR(fld, lerpfrac) \ 157 FIELD_SCALAR(fld, light_lev) \ 158 FIELD_SCALAR(fld, lip) \ 159 FIELD_SCALAR(fld, loddistance1) \ 160 FIELD_SCALAR(fld, lodmodel1) \ 161 FIELD_SCALAR(fld, lodmodel2) \ 162 FIELD_SCALAR(fld, ltime) \ 163 FIELD_SCALAR(fld, map) \ 164 FIELD_SCALAR(fld, max_health) \ 165 FIELD_SCALAR(fld, mdl) \ 166 FIELD_SCALAR(fld, message2) \ 167 FIELD_SCALAR(fld, message) \ 168 FIELD_SCALAR(fld, modelindex) \ 169 FIELD_SCALAR(fld, modelscale) \ 170 FIELD_SCALAR(fld, model) \ 171 FIELD_SCALAR(fld, monsterid) \ 172 FIELD_SCALAR(fld, monster_moveflags) \ 173 FIELD_SCALAR(fld, monster_name) \ 174 FIELD_SCALAR(fld, movetype) \ 175 FIELD_SCALAR(fld, move_movetype) \ 176 FIELD_SCALAR(fld, netname) \ 177 FIELD_SCALAR(fld, nextthink) \ 178 FIELD_SCALAR(fld, noalign) \ 179 FIELD_SCALAR(fld, noise1) \ 180 FIELD_SCALAR(fld, noise2) \ 181 FIELD_SCALAR(fld, noise3) \ 182 FIELD_SCALAR(fld, noise) \ 183 FIELD_SCALAR(fld, notcpm) \ 184 FIELD_SCALAR(fld, notfree) \ 185 FIELD_SCALAR(fld, notsingle) \ 186 FIELD_SCALAR(fld, notta) \ 187 FIELD_SCALAR(fld, notteam) \ 188 FIELD_SCALAR(fld, notvq3) \ 189 FIELD_SCALAR(fld, phase) \ 190 FIELD_SCALAR(fld, platmovetype) \ 191 FIELD_SCALAR(fld, race_place) \ 192 FIELD_SCALAR(fld, speed_finished) \ 193 FIELD_SCALAR(fld, strength_finished) \ 194 FIELD_SCALAR(fld, radius) \ 195 FIELD_SCALAR(fld, respawntimestart) \ 196 FIELD_SCALAR(fld, respawntimejitter) \ 197 FIELD_SCALAR(fld, respawntime) \ 198 FIELD_SCALAR(fld, restriction) \ 199 FIELD_SCALAR(fld, scale) \ 200 FIELD_SCALAR(fld, skin) \ 201 FIELD_SCALAR(fld, solid) \ 202 FIELD_SCALAR(fld, sound1) \ 203 FIELD_SCALAR(fld, sounds) \ 204 FIELD_SCALAR(fld, spawnflags) \ 205 FIELD_SCALAR(fld, spawnmob) \ 206 FIELD_SCALAR(fld, speed) \ 207 FIELD_SCALAR(fld, strength) \ 208 FIELD_SCALAR(fld, style) \ 209 FIELD_SCALAR(fld, target2) \ 210 FIELD_SCALAR(fld, target3) \ 211 FIELD_SCALAR(fld, target4) \ 212 FIELD_SCALAR(fld, targetname) \ 213 FIELD_SCALAR(fld, target) \ 214 FIELD_SCALAR(fld, target_random) \ 215 FIELD_SCALAR(fld, target_range) \ 216 FIELD_SCALAR(fld, team) \ 217 FIELD_SCALAR(fld, trigger_reverse) \ 218 FIELD_SCALAR(fld, turret_scale_aim) \ 219 FIELD_SCALAR(fld, turret_scale_ammo) \ 220 FIELD_SCALAR(fld, turret_scale_damage) \ 221 FIELD_SCALAR(fld, turret_scale_health) \ 222 FIELD_SCALAR(fld, turret_scale_range) \ 223 FIELD_SCALAR(fld, turret_scale_refire) \ 224 FIELD_SCALAR(fld, turret_scale_respawn) \ 225 FIELD_SCALAR(fld, volume) \ 226 FIELD_SCALAR(fld, wait) \ 227 FIELD_SCALAR(fld, warpzone_fadeend) \ 228 FIELD_SCALAR(fld, warpzone_fadestart) \ 229 FIELD_SCALAR(fld, weapon) \ 230 FIELD_SCALAR(fld, worldtype) \ 231 FIELD_VEC(fld, absmax) \ 232 FIELD_VEC(fld, absmin) \ 233 FIELD_VEC(fld, angles) \ 234 FIELD_VEC(fld, avelocity) \ 235 FIELD_VEC(fld, beam_color)\ 236 FIELD_VEC(fld, debrisavelocityjitter) \ 237 FIELD_VEC(fld, debrisvelocity) \ 238 FIELD_VEC(fld, debrisvelocityjitter) \ 239 FIELD_VEC(fld, color) \ 240 FIELD_VEC(fld, mangle) \ 241 FIELD_VEC(fld, maxs) \ 242 FIELD_VEC(fld, mins) \ 243 FIELD_VEC(fld, modelscale_vec) \ 244 FIELD_VEC(fld, velocity) \ 248 void _checkWhitelisted(
entity this,
string id)
250 for (
int i = 0, n = numentityfields(); i < n; ++i)
252 string value = getentityfieldstring(i,
this);
253 string s = entityfieldname(i);
254 FIELDS_UNION(_spawnfunc_checktypes)
255 if (value ==
"")
continue;
256 if (s ==
"")
continue;
257 FIELDS_COMMON(_spawnfunc_check)
258 FIELDS_UNION(_spawnfunc_check)
259 LOG_WARNF(_(
"Entity field %s.%s (%s) is not whitelisted. If you believe this is an error, please file an issue."),
id, s, value);
265 void g_spawn_queue_spawn() { g_spawn_queue =
IL_NEW(); }
267 noref
bool __spawnfunc_first;
269 #define spawnfunc(id) \ 270 void __spawnfunc_##id(entity this); \ 271 ACCUMULATE void spawnfunc_##id(entity this) \ 273 if (!__spawnfunc_first) { \ 274 __spawnfunc_first = true; \ 275 static_init_early(); \ 277 bool dospawn = true; \ 278 if (__spawnfunc_expecting > 1) { __spawnfunc_expecting = 0; } \ 279 else if (__spawnfunc_expecting) { \ 281 if (!g_spawn_queue) g_spawn_queue_spawn(); \ 282 __spawnfunc_expecting = 0; \ 283 this = __spawnfunc_expect; \ 284 __spawnfunc_expect = NULL; \ 290 if (!this.sourceLoc) { \ 291 this.sourceLoc = __FILE__":"STR(__LINE__); \ 293 this.classname = #id; \ 294 if (!this.spawnfunc_checked) { \ 295 _checkWhitelisted(this, #id); \ 296 if (__fullspawndata) { \ 299 this.fullspawndata = __fullspawndata; \ 301 this.spawnfunc_checked = true; \ 305 this.think = func_null; \ 306 this.nextthink = 0; \ 307 __spawnfunc_defer(this, __spawnfunc_##id); \ 310 this.__spawnfunc_constructor = __spawnfunc_##id; \ 313 if (dospawn) { __spawnfunc_##id(this); } \ 314 if (__spawnfunc_unreachable_workaround) return; \ 316 void __spawnfunc_##id(entity this)
limitations: NULL cannot be present elements can only be present once a maximum of IL_MAX lists can e...
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.