]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/target_spawn.qc
allow target_spawn to edit entities too
[divverent/nexuiz.git] / data / qcsrc / server / target_spawn.qc
1 // spawner entity
2 // "classname" "target_spawn"
3 // "message" "fieldname value fieldname value ..."
4 // "spawnflags"
5 //   1 = call the spawn function
6 //   2 = trigger on map load
7
8 float target_spawn_initialized;
9 .void() target_spawn_spawnfunc;
10 float target_spawn_spawnfunc_field;
11 .entity target_spawn_activator;
12
13 void target_spawn_useon(entity e)
14 {
15         float i, n, valuefieldpos, sPWNed;
16         string key, value, valuefield, valueoffset, valueoffsetrandom;
17         entity valueent;
18         vector data, data2;
19         entity oldself;
20         entity oldactivator;
21
22         n = tokenize_sane(self.message);
23
24         sPWNed = FALSE;
25
26         for(i = 0; i < n-1; i += 2)
27         {
28                 key = argv(i);
29                 value = argv(i+1);
30                 data = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", key)));
31                 if(data_y == 0) // undefined field, i.e., invalid type
32                 {
33                         print("target_spawn: invalid/unknown entity key ", key, " specified, ignored!\n");
34                         continue;
35                 }
36                 if(substring(value, 0, 1) == "$")
37                 {
38                         value = substring(value, 1, strlen(value) - 1);
39                         if(substring(value, 0, 1) == "$")
40                         {
41                                 // deferred replacement
42                                 // do nothing
43                                 // useful for creating target_spawns with this!
44                         }
45                         else
46                         {
47                                 // replace me!
48                                 valuefieldpos = strstrofs(value, ".", 0);
49                                 valuefield = "";
50                                 if(valuefieldpos != -1)
51                                 {
52                                         valuefield = substring(value, valuefieldpos + 1, strlen(value) - valuefieldpos - 1);
53                                         value = substring(value, 0, valuefieldpos);
54                                 }
55
56                                 valuefieldpos = strstrofs(value, "+", 0);
57                                 valueoffset = "";
58                                 if(valuefieldpos != -1)
59                                 {
60                                         valueoffset = substring(valuefield, valuefieldpos + 1, strlen(valueoffset) - valuefieldpos - 1);
61                                         valuefield = substring(valuefield, 0, valuefieldpos);
62                                 }
63
64                                 valuefieldpos = strstrofs(valueoffset, "+", 0);
65                                 valueoffsetrandom = "";
66                                 if(valuefieldpos != -1)
67                                 {
68                                         valueoffsetrandom = substring(valueoffset, valuefieldpos + 1, strlen(valueoffset) - valuefieldpos - 1);
69                                         valueoffset = substring(valueoffset, 0, valuefieldpos);
70                                 }
71
72                                 if(value == "self")
73                                 {
74                                         valueent = self;
75                                         value = "";
76                                 }
77                                 else if(value == "activator")
78                                 {
79                                         valueent = activator;
80                                         value = "";
81                                 }
82                                 else if(value == "pusher")
83                                 {
84                                         if(time < activator.pushltime)
85                                                 valueent = activator.pusher;
86                                         else
87                                                 valueent = world;
88                                         value = "";
89                                 }
90                                 else if(value == "time")
91                                 {
92                                         valueent = world;
93                                         value = ftos(time);
94                                 }
95                                 else
96                                 {
97                                         print("target_spawn: invalid/unknown variable replacement ", value, " specified, ignored!\n");
98                                         continue;
99                                 }
100
101                                 if(valuefield == "")
102                                 {
103                                         if(value == "")
104                                                 value = ftos(num_for_edict(valueent));
105                                 }
106                                 else
107                                 {
108                                         if(value != "")
109                                         {
110                                                 print("target_spawn: try to get a field of a non-entity, ignored!\n");
111                                                 continue;
112                                         }
113                                         data2 = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", valuefield)));
114                                         if(data2_y == 0) // undefined field, i.e., invalid type
115                                         {
116                                                 print("target_spawn: invalid/unknown entity key replacement ", value, " specified, ignored!\n");
117                                                 continue;
118                                         }
119                                         value = getentityfieldstring(data2_x, valueent);
120                                 }
121
122                                 if(valueoffset != "")
123                                 {
124                                         switch(data_y)
125                                         {
126                                                 case FIELD_STRING:
127                                                         value = strcat(value, valueoffset);
128                                                         break;
129                                                 case FIELD_FLOAT:
130                                                         value = ftos(stof(value) + stof(valueoffset));
131                                                         break;
132                                                 case FIELD_VECTOR:
133                                                         value = vtos(stov(value) + stov(valueoffset));
134                                                         break;
135                                                 default:
136                                                         print("target_spawn: only string, float and vector fields can do calculations, calculation ignored!\n");
137                                                         break;
138                                         }
139                                 }
140
141                                 if(valueoffsetrandom != "")
142                                 {
143                                         switch(data_y)
144                                         {
145                                                 case FIELD_FLOAT:
146                                                         value = ftos(stof(value) + random() * stof(valueoffsetrandom));
147                                                         break;
148                                                 case FIELD_VECTOR:
149                                                         data2 = stov(valueoffsetrandom);
150                                                         value = vtos(stov(value) + random() * data2_x * '1 0 0' + random() * data2_y * '0 1 0' + random() * data2_z * '0 0 1');
151                                                         break;
152                                                 default:
153                                                         print("target_spawn: only float and vector fields can do random calculations, calculation ignored!\n");
154                                                         break;
155                                         }
156                                 }
157                         }
158                 }
159                 putentityfieldstring(data_x, e, value);
160
161                 if(key == "classname" && !sPWNed)
162                 {
163                         if(self.spawnflags & 1)
164                         {
165                                 if(!e.target_spawn_spawnfunc)
166                                         putentityfieldstring(target_spawn_spawnfunc_field, e, strcat("spawnfunc_", value));
167
168                                 oldself = self;
169                                 oldactivator = activator;
170
171                                 self = e;
172                                 activator = self.target_spawn_activator;
173
174                                 self.target_spawn_spawnfunc();
175
176                                 self = oldself;
177                                 activator = oldactivator;
178                         }
179                         sPWNed = TRUE;
180                 }
181         }
182 }
183
184 void target_spawn_use()
185 {
186         entity e;
187
188         if(self.target == "")
189         {
190                 // spawn new entity
191                 e = spawn();
192                 target_spawn_useon(e);
193         }
194         else
195         {
196                 // edit entity
197                 for(e = world; (e = find(e, targetname, self.target)); )
198                         target_spawn_useon(e);
199         }
200 }
201
202 void target_spawn_spawnfirst()
203 {
204         activator = self.target_spawn_activator;
205         target_spawn_use();
206 }
207
208 void spawnfunc_target_spawn()
209 {
210         if(!target_spawn_initialized)
211         {
212                 float n, i;
213                 string fn;
214                 float ft;
215
216                 n = numentityfields();
217                 for(i = 0; i < n; ++i)
218                 {
219                         fn = entityfieldname(i);
220                         ft = entityfieldtype(i);
221                         db_put(TemporaryDB, strcat("/target_spawn/field/", fn), vtos(i * '1 0 0' + ft * '0 1 0' + '0 0 1'));
222                         if(fn == "target_spawn_spawnfunc")
223                                 target_spawn_spawnfunc_field = i;
224                 }
225
226                 target_spawn_initialized = 1;
227         }
228         self.use = target_spawn_use;
229         InitializeEntity(self, target_spawn_spawnfirst, INITPRIO_LAST);
230 }