]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/spawnfunc.qh
c474104d6eadf6c509634885d24559c60a814d11
[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 bool entityfieldassignablefromeditor(int i) {
9     switch (entityfieldtype(i)) {
10         case FIELD_STRING:
11         case FIELD_FLOAT:
12         case FIELD_VECTOR:
13             return true;
14     }
15     return false;
16 }
17
18 #define _spawnfunc_checktypes(fld) if (fieldname == #fld) \
19     if (!entityfieldassignablefromeditor(i)) LOG_FATALF("Entity field '%s' cannot be whitelisted\n", fieldname);
20 #define _spawnfunc_check(fld) if (fieldname == #fld) \
21     continue;
22
23 #define spawnfunc_1(id, whitelist) spawnfunc_2(id, whitelist)
24 #define spawnfunc_2(id, whitelist) void spawnfunc_##id(entity this) { \
25     this = self; \
26     if (!this.spawnfunc_checked) { \
27         for (int i = 0, n = numentityfields(); i < n; ++i) { \
28             string value = getentityfieldstring(i, this); \
29             string fieldname = entityfieldname(i); \
30             whitelist(_spawnfunc_checktypes) \
31             if (value == "") continue; \
32             if (fieldname == "") continue; \
33             FIELDS_COMMON(_spawnfunc_check) \
34             whitelist(_spawnfunc_check) \
35             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); \
36         } \
37         this.spawnfunc_checked = true; \
38     } \
39 } \
40 [[accumulate]] void spawnfunc_##id(entity this)
41
42 #define FIELD_SCALAR(fld, n) \
43     fld(n)
44 #define FIELD_VEC(fld, n) \
45     fld(n) \
46     fld(n##_x) \
47     fld(n##_y) \
48     fld(n##_z)
49
50 #define FIELDS_NONE(fld)
51 #define FIELDS_ALL(fld) if (false)
52
53 #define FIELDS_COMMON(fld) \
54     FIELD_SCALAR(fld, classname) \
55     FIELD_SCALAR(fld, spawnfunc_checked) \
56     /**/
57
58 #define FIELDS_UNION(fld) \
59     FIELD_SCALAR(fld, Version) \
60     FIELD_SCALAR(fld, ammo_cells) \
61     FIELD_SCALAR(fld, ammo_nails) \
62     FIELD_SCALAR(fld, ammo_rockets) \
63     FIELD_SCALAR(fld, armorvalue) \
64     FIELD_SCALAR(fld, atten) \
65     FIELD_SCALAR(fld, bgmscriptdecay) \
66     FIELD_SCALAR(fld, bgmscriptsustain) \
67     FIELD_SCALAR(fld, bgmscript) \
68     FIELD_SCALAR(fld, button0) \
69     FIELD_SCALAR(fld, cnt) \
70     FIELD_SCALAR(fld, colormap) \
71     FIELD_SCALAR(fld, count) \
72     FIELD_SCALAR(fld, debrisdamageforcescale) \
73     FIELD_SCALAR(fld, debrisfadetime) \
74     FIELD_SCALAR(fld, debristimejitter) \
75     FIELD_SCALAR(fld, debristime) \
76     FIELD_SCALAR(fld, debris) \
77     FIELD_SCALAR(fld, delay) \
78     FIELD_SCALAR(fld, dmg) \
79     FIELD_SCALAR(fld, dmg_edge) \
80     FIELD_SCALAR(fld, dmg_force) \
81     FIELD_SCALAR(fld, dmg_radius) \
82     FIELD_SCALAR(fld, effects) \
83     FIELD_SCALAR(fld, flags) \
84     FIELD_SCALAR(fld, fog) \
85     FIELD_SCALAR(fld, frame) \
86     FIELD_SCALAR(fld, gametypefilter) \
87     FIELD_SCALAR(fld, gravity) \
88     FIELD_SCALAR(fld, health) \
89     FIELD_SCALAR(fld, height) \
90     FIELD_SCALAR(fld, impulse) \
91     FIELD_SCALAR(fld, killtarget) \
92     FIELD_SCALAR(fld, lerpfrac) \
93     FIELD_SCALAR(fld, light_lev) \
94     FIELD_SCALAR(fld, lip) \
95     FIELD_SCALAR(fld, loddistance1) \
96     FIELD_SCALAR(fld, lodmodel1) \
97     FIELD_SCALAR(fld, ltime) \
98     FIELD_SCALAR(fld, mdl) \
99     FIELD_SCALAR(fld, message2) \
100     FIELD_SCALAR(fld, message) \
101     FIELD_SCALAR(fld, modelindex) \
102     FIELD_SCALAR(fld, modelscale) \
103     FIELD_SCALAR(fld, model) \
104     FIELD_SCALAR(fld, movetype) \
105     FIELD_SCALAR(fld, netname) \
106     FIELD_SCALAR(fld, nextthink) \
107     FIELD_SCALAR(fld, noalign) \
108     FIELD_SCALAR(fld, noise1) \
109     FIELD_SCALAR(fld, noise2) \
110     FIELD_SCALAR(fld, noise) \
111     FIELD_SCALAR(fld, phase) \
112     FIELD_SCALAR(fld, race_place) \
113     FIELD_SCALAR(fld, radius) \
114     FIELD_SCALAR(fld, respawntimejitter) \
115     FIELD_SCALAR(fld, respawntime) \
116     FIELD_SCALAR(fld, restriction) \
117     FIELD_SCALAR(fld, scale) \
118     FIELD_SCALAR(fld, skin) \
119     FIELD_SCALAR(fld, solid) \
120     FIELD_SCALAR(fld, sound1) \
121     FIELD_SCALAR(fld, sounds) \
122     FIELD_SCALAR(fld, spawnflags) \
123     FIELD_SCALAR(fld, speed) \
124     FIELD_SCALAR(fld, strength) \
125     FIELD_SCALAR(fld, target2) \
126     FIELD_SCALAR(fld, target3) \
127     FIELD_SCALAR(fld, target4) \
128     FIELD_SCALAR(fld, targetname) \
129     FIELD_SCALAR(fld, target) \
130     FIELD_SCALAR(fld, target_random) \
131     FIELD_SCALAR(fld, team) \
132     FIELD_SCALAR(fld, turret_scale_health) \
133     FIELD_SCALAR(fld, turret_scale_range) \
134     FIELD_SCALAR(fld, turret_scale_respawn) \
135     FIELD_SCALAR(fld, volume) \
136     FIELD_SCALAR(fld, wait) \
137     FIELD_SCALAR(fld, warpzone_fadeend) \
138     FIELD_SCALAR(fld, warpzone_fadestart) \
139     FIELD_VEC(fld, absmax) \
140     FIELD_VEC(fld, absmin) \
141     FIELD_VEC(fld, angles) \
142     FIELD_VEC(fld, avelocity) \
143     FIELD_VEC(fld, maxs) \
144     FIELD_VEC(fld, maxs) \
145     FIELD_VEC(fld, mins) \
146     FIELD_VEC(fld, modelscale_vec) \
147     FIELD_VEC(fld, origin) \
148     FIELD_VEC(fld, velocity) \
149     /**/
150
151 #define spawnfunc(...) EVAL(OVERLOAD(spawnfunc, __VA_ARGS__, FIELDS_UNION))
152
153 #endif