7 // "classname" "target_spawn"
8 // "message" "fieldname value fieldname value ..."
10 // 1 = call the spawn function
11 // 2 = trigger on map load
13 float target_spawn_initialized;
14 .void() target_spawn_spawnfunc;
15 float target_spawn_spawnfunc_field;
16 .entity target_spawn_activator;
17 .float target_spawn_id;
18 float target_spawn_count;
20 void target_spawn_helper_setmodel()
22 setmodel(self, self.model);
25 void target_spawn_helper_setsize()
27 setsize(self, self.mins, self.maxs);
30 void target_spawn_edit_entity(entity e, string msg, entity kt, entity t2, entity t3, entity t4, entity act)
32 float i, n, valuefieldpos;
33 string key, value, valuefield, valueoffset, valueoffsetrandom;
39 n = tokenize_console(msg);
41 for(i = 0; i < n-1; i += 2)
48 data.y = FIELD_STRING;
52 data = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", key)));
53 if(data.y == 0) // undefined field, i.e., invalid type
55 print("target_spawn: invalid/unknown entity key ", key, " specified, ignored!\n");
59 if(substring(value, 0, 1) == "$")
61 value = substring(value, 1, strlen(value) - 1);
62 if(substring(value, 0, 1) == "$")
64 // deferred replacement
66 // useful for creating target_spawns with this!
71 valuefieldpos = strstrofs(value, "+", 0);
73 if(valuefieldpos != -1)
75 valueoffset = substring(value, valuefieldpos + 1, strlen(value) - valuefieldpos - 1);
76 value = substring(value, 0, valuefieldpos);
79 valuefieldpos = strstrofs(valueoffset, "+", 0);
80 valueoffsetrandom = "";
81 if(valuefieldpos != -1)
83 valueoffsetrandom = substring(valueoffset, valuefieldpos + 1, strlen(valueoffset) - valuefieldpos - 1);
84 valueoffset = substring(valueoffset, 0, valuefieldpos);
87 valuefieldpos = strstrofs(value, ".", 0);
89 if(valuefieldpos != -1)
91 valuefield = substring(value, valuefieldpos + 1, strlen(value) - valuefieldpos - 1);
92 value = substring(value, 0, valuefieldpos);
100 else if(value == "activator")
105 else if(value == "other")
110 else if(value == "pusher")
112 if(time < act.pushltime)
113 valueent = act.pusher;
118 else if(value == "target")
123 else if(value == "killtarget")
128 else if(value == "target2")
133 else if(value == "target3")
138 else if(value == "target4")
143 else if(value == "time")
150 print("target_spawn: invalid/unknown variable replacement ", value, " specified, ignored!\n");
157 value = ftos(num_for_edict(valueent));
163 print("target_spawn: try to get a field of a non-entity, ignored!\n");
166 data2 = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", valuefield)));
167 if(data2_y == 0) // undefined field, i.e., invalid type
169 print("target_spawn: invalid/unknown entity key replacement ", valuefield, " specified, ignored!\n");
172 value = getentityfieldstring(data2_x, valueent);
175 if(valueoffset != "")
180 value = strcat(value, valueoffset);
183 value = ftos(stof(value) + stof(valueoffset));
186 value = vtos(stov(value) + stov(valueoffset));
189 print("target_spawn: only string, float and vector fields can do calculations, calculation ignored!\n");
194 if(valueoffsetrandom != "")
199 value = ftos(stof(value) + random() * stof(valueoffsetrandom));
202 data2 = stov(valueoffsetrandom);
203 value = vtos(stov(value) + random() * data2_x * '1 0 0' + random() * data2_y * '0 1 0' + random() * data2_z * '0 0 1');
206 print("target_spawn: only float and vector fields can do random calculations, calculation ignored!\n");
214 if(substring(value, 0, 1) == "_")
215 value = strcat("target_spawn_helper", value);
216 putentityfieldstring(target_spawn_spawnfunc_field, e, value);
219 oldactivator = activator;
224 self.target_spawn_spawnfunc();
227 activator = oldactivator;
229 // We called an external function, so we have to re-tokenize msg.
230 n = tokenize_console(msg);
234 if(data.y == FIELD_VECTOR)
235 value = strreplace("'", "", value); // why?!?
236 putentityfieldstring(data.x, e, value);
241 void target_spawn_useon(entity e)
243 self.target_spawn_activator = activator;
244 target_spawn_edit_entity(
247 find(world, targetname, self.killtarget),
248 find(world, targetname, self.target2),
249 find(world, targetname, self.target3),
250 find(world, targetname, self.target4),
255 float target_spawn_cancreate()
261 if(c == 0) // no limit?
264 ++c; // increase count to not include MYSELF
265 for(e = world; (e = findfloat(e, target_spawn_id, self.target_spawn_id)); --c)
268 // if c now is 0, we have AT LEAST the given count (maybe more), so don't spawn any more
274 void target_spawn_use()
278 if(self.target == "")
281 if(!target_spawn_cancreate())
284 target_spawn_useon(e);
285 e.target_spawn_id = self.target_spawn_id;
287 else if(self.target == "*activator")
291 target_spawn_useon(activator);
296 for(e = world; (e = find(e, targetname, self.target)); )
297 target_spawn_useon(e);
301 void target_spawn_spawnfirst()
303 activator = self.target_spawn_activator;
304 if(self.spawnflags & 2)
308 void initialize_field_db()
310 if(!target_spawn_initialized)
317 n = numentityfields();
318 for(i = 0; i < n; ++i)
320 fn = entityfieldname(i);
321 ft = entityfieldtype(i);
322 next = i * '1 0 0' + ft * '0 1 0' + '0 0 1';
323 prev = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", fn)));
326 db_put(TemporaryDB, strcat("/target_spawn/field/", fn), vtos(next));
327 if(fn == "target_spawn_spawnfunc")
328 target_spawn_spawnfunc_field = i;
332 target_spawn_initialized = 1;
336 void spawnfunc_target_spawn()
338 initialize_field_db();
339 self.use = target_spawn_use;
340 self.message = strzone(strreplace("'", "\"", self.message));
341 self.target_spawn_id = ++target_spawn_count;
342 InitializeEntity(self, target_spawn_spawnfirst, INITPRIO_LAST);
346 void trigger_relay_if_use()
351 // TODO make this generic AND faster than nextent()ing through all, if somehow possible
352 n = (cvar_string(self.netname) == cvar_string(self.message));
353 if(self.spawnflags & 1)
360 void spawnfunc_trigger_relay_if()
362 self.use = trigger_relay_if_use;