3 // "classname" "target_spawn"
4 // "message" "fieldname value fieldname value ..."
6 // 1 = call the spawn function
7 // 2 = trigger on map load
9 float target_spawn_initialized;
10 .void() target_spawn_spawnfunc;
11 float target_spawn_spawnfunc_field;
12 .entity target_spawn_activator;
13 .float target_spawn_id;
14 float target_spawn_count;
16 void target_spawn_helper_setmodel()
18 setmodel(self, self.model);
21 void target_spawn_helper_setsize()
23 setsize(self, self.mins, self.maxs);
26 void target_spawn_edit_entity(entity e, string msg, entity kt, entity t2, entity t3, entity t4, entity act)
28 float i, n, valuefieldpos;
29 string key, value, valuefield, valueoffset, valueoffsetrandom;
35 n = tokenize_console(msg);
37 for(i = 0; i < n-1; i += 2)
44 data_y = FIELD_STRING;
48 data = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", key)));
49 if(data_y == 0) // undefined field, i.e., invalid type
51 print("target_spawn: invalid/unknown entity key ", key, " specified, ignored!\n");
55 if(substring(value, 0, 1) == "$")
57 value = substring(value, 1, strlen(value) - 1);
58 if(substring(value, 0, 1) == "$")
60 // deferred replacement
62 // useful for creating target_spawns with this!
67 valuefieldpos = strstrofs(value, "+", 0);
69 if(valuefieldpos != -1)
71 valueoffset = substring(value, valuefieldpos + 1, strlen(value) - valuefieldpos - 1);
72 value = substring(value, 0, valuefieldpos);
75 valuefieldpos = strstrofs(valueoffset, "+", 0);
76 valueoffsetrandom = "";
77 if(valuefieldpos != -1)
79 valueoffsetrandom = substring(valueoffset, valuefieldpos + 1, strlen(valueoffset) - valuefieldpos - 1);
80 valueoffset = substring(valueoffset, 0, valuefieldpos);
83 valuefieldpos = strstrofs(value, ".", 0);
85 if(valuefieldpos != -1)
87 valuefield = substring(value, valuefieldpos + 1, strlen(value) - valuefieldpos - 1);
88 value = substring(value, 0, valuefieldpos);
96 else if(value == "activator")
101 else if(value == "other")
106 else if(value == "pusher")
108 if(time < act.pushltime)
109 valueent = act.pusher;
114 else if(value == "target")
119 else if(value == "killtarget")
124 else if(value == "target2")
129 else if(value == "target3")
134 else if(value == "target4")
139 else if(value == "time")
146 print("target_spawn: invalid/unknown variable replacement ", value, " specified, ignored!\n");
153 value = ftos(num_for_edict(valueent));
159 print("target_spawn: try to get a field of a non-entity, ignored!\n");
162 data2 = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", valuefield)));
163 if(data2_y == 0) // undefined field, i.e., invalid type
165 print("target_spawn: invalid/unknown entity key replacement ", valuefield, " specified, ignored!\n");
168 value = getentityfieldstring(data2_x, valueent);
171 if(valueoffset != "")
176 value = strcat(value, valueoffset);
179 value = ftos(stof(value) + stof(valueoffset));
182 value = vtos(stov(value) + stov(valueoffset));
185 print("target_spawn: only string, float and vector fields can do calculations, calculation ignored!\n");
190 if(valueoffsetrandom != "")
195 value = ftos(stof(value) + random() * stof(valueoffsetrandom));
198 data2 = stov(valueoffsetrandom);
199 value = vtos(stov(value) + random() * data2_x * '1 0 0' + random() * data2_y * '0 1 0' + random() * data2_z * '0 0 1');
202 print("target_spawn: only float and vector fields can do random calculations, calculation ignored!\n");
210 if(substring(value, 0, 1) == "_")
211 value = strcat("target_spawn_helper", value);
212 putentityfieldstring(target_spawn_spawnfunc_field, e, value);
215 oldactivator = activator;
220 self.target_spawn_spawnfunc();
223 activator = oldactivator;
227 if(data_y == FIELD_VECTOR)
228 value = strreplace("'", "", value); // why?!?
229 putentityfieldstring(data_x, e, value);
234 void target_spawn_useon(entity e)
236 self.target_spawn_activator = activator;
237 target_spawn_edit_entity(
240 find(world, targetname, self.killtarget),
241 find(world, targetname, self.target2),
242 find(world, targetname, self.target3),
243 find(world, targetname, self.target4),
248 float target_spawn_cancreate()
254 if(c == 0) // no limit?
257 ++c; // increase count to not include MYSELF
258 for(e = world; (e = findfloat(e, target_spawn_id, self.target_spawn_id)); --c)
261 // if c now is 0, we have AT LEAST the given count (maybe more), so don't spawn any more
267 void target_spawn_use()
271 if(self.target == "")
274 if(!target_spawn_cancreate())
277 target_spawn_useon(e);
278 e.target_spawn_id = self.target_spawn_id;
280 else if(self.target == "*activator")
284 target_spawn_useon(activator);
289 for(e = world; (e = find(e, targetname, self.target)); )
290 target_spawn_useon(e);
294 void target_spawn_spawnfirst()
296 activator = self.target_spawn_activator;
297 if(self.spawnflags & 2)
301 void initialize_field_db()
303 if(!target_spawn_initialized)
310 n = numentityfields();
311 for(i = 0; i < n; ++i)
313 fn = entityfieldname(i);
314 ft = entityfieldtype(i);
315 new = i * '1 0 0' + ft * '0 1 0' + '0 0 1';
316 prev = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", fn)));
319 db_put(TemporaryDB, strcat("/target_spawn/field/", fn), vtos(new));
320 if(fn == "target_spawn_spawnfunc")
321 target_spawn_spawnfunc_field = i;
325 target_spawn_initialized = 1;
329 void spawnfunc_target_spawn()
331 initialize_field_db();
332 self.use = target_spawn_use;
333 self.message = strzone(strreplace("'", "\"", self.message));
334 self.target_spawn_id = ++target_spawn_count;
335 InitializeEntity(self, target_spawn_spawnfirst, INITPRIO_LAST);