4 #include "../../util.qh"
5 #include "../../../server/defs.qh"
11 // "classname" "target_spawn"
12 // "message" "fieldname value fieldname value ..."
14 // 1 = call the spawn function
15 // 2 = trigger on map load
17 float target_spawn_initialized;
18 .void() target_spawn_spawnfunc;
19 float target_spawn_spawnfunc_field;
20 .entity target_spawn_activator;
21 .float target_spawn_id;
22 float target_spawn_count;
24 void target_spawn_helper_setmodel()
26 _setmodel(self, self.model);
29 void target_spawn_helper_setsize()
31 setsize(self, self.mins, self.maxs);
34 void target_spawn_edit_entity(entity e, string msg, entity kt, entity t2, entity t3, entity t4, entity act)
36 float i, n, valuefieldpos;
37 string key, value, valuefield, valueoffset, valueoffsetrandom;
42 n = tokenize_console(msg);
44 for(i = 0; i < n-1; i += 2)
51 data.y = FIELD_STRING;
55 data = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", key)));
56 if(data.y == 0) // undefined field, i.e., invalid type
58 LOG_INFO("target_spawn: invalid/unknown entity key ", key, " specified, ignored!\n");
62 if(substring(value, 0, 1) == "$")
64 value = substring(value, 1, strlen(value) - 1);
65 if(substring(value, 0, 1) == "$")
67 // deferred replacement
69 // useful for creating target_spawns with this!
74 valuefieldpos = strstrofs(value, "+", 0);
76 if(valuefieldpos != -1)
78 valueoffset = substring(value, valuefieldpos + 1, strlen(value) - valuefieldpos - 1);
79 value = substring(value, 0, valuefieldpos);
82 valuefieldpos = strstrofs(valueoffset, "+", 0);
83 valueoffsetrandom = "";
84 if(valuefieldpos != -1)
86 valueoffsetrandom = substring(valueoffset, valuefieldpos + 1, strlen(valueoffset) - valuefieldpos - 1);
87 valueoffset = substring(valueoffset, 0, valuefieldpos);
90 valuefieldpos = strstrofs(value, ".", 0);
92 if(valuefieldpos != -1)
94 valuefield = substring(value, valuefieldpos + 1, strlen(value) - valuefieldpos - 1);
95 value = substring(value, 0, valuefieldpos);
103 else if(value == "activator")
108 else if(value == "other")
113 else if(value == "pusher")
115 if(time < act.pushltime)
116 valueent = act.pusher;
121 else if(value == "target")
126 else if(value == "killtarget")
131 else if(value == "target2")
136 else if(value == "target3")
141 else if(value == "target4")
146 else if(value == "time")
153 LOG_INFO("target_spawn: invalid/unknown variable replacement ", value, " specified, ignored!\n");
160 value = ftos(num_for_edict(valueent));
166 LOG_INFO("target_spawn: try to get a field of a non-entity, ignored!\n");
169 data2 = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", valuefield)));
170 if(data2_y == 0) // undefined field, i.e., invalid type
172 LOG_INFO("target_spawn: invalid/unknown entity key replacement ", valuefield, " specified, ignored!\n");
175 value = getentityfieldstring(data2_x, valueent);
178 if(valueoffset != "")
183 value = strcat(value, valueoffset);
186 value = ftos(stof(value) + stof(valueoffset));
189 value = vtos(stov(value) + stov(valueoffset));
192 LOG_INFO("target_spawn: only string, float and vector fields can do calculations, calculation ignored!\n");
197 if(valueoffsetrandom != "")
202 value = ftos(stof(value) + random() * stof(valueoffsetrandom));
205 data2 = stov(valueoffsetrandom);
206 value = vtos(stov(value) + random() * data2_x * '1 0 0' + random() * data2_y * '0 1 0' + random() * data2_z * '0 0 1');
209 LOG_INFO("target_spawn: only float and vector fields can do random calculations, calculation ignored!\n");
217 if(substring(value, 0, 1) == "_")
218 value = strcat("target_spawn_helper", value);
219 putentityfieldstring(target_spawn_spawnfunc_field, e, value);
221 oldactivator = activator;
224 WITH(entity, self, e, e.target_spawn_spawnfunc());
225 activator = oldactivator;
227 // We called an external function, so we have to re-tokenize msg.
228 n = tokenize_console(msg);
232 if(data.y == FIELD_VECTOR)
233 value = strreplace("'", "", value); // why?!?
234 putentityfieldstring(data.x, e, value);
239 void target_spawn_useon(entity e)
241 self.target_spawn_activator = activator;
242 target_spawn_edit_entity(
245 find(world, targetname, self.killtarget),
246 find(world, targetname, self.target2),
247 find(world, targetname, self.target3),
248 find(world, targetname, self.target4),
253 float target_spawn_cancreate()
259 if(c == 0) // no limit?
262 ++c; // increase count to not include MYSELF
263 for(e = world; (e = findfloat(e, target_spawn_id, self.target_spawn_id)); --c)
266 // if c now is 0, we have AT LEAST the given count (maybe more), so don't spawn any more
272 void target_spawn_use()
276 if(self.target == "")
279 if(!target_spawn_cancreate())
282 e.spawnfunc_checked = true;
283 target_spawn_useon(e);
284 e.target_spawn_id = self.target_spawn_id;
286 else if(self.target == "*activator")
290 target_spawn_useon(activator);
295 for(e = world; (e = find(e, targetname, self.target)); )
296 target_spawn_useon(e);
300 void target_spawn_spawnfirst()
302 activator = self.target_spawn_activator;
303 if(self.spawnflags & 2)
307 void initialize_field_db()
309 if(!target_spawn_initialized)
316 n = numentityfields();
317 for(i = 0; i < n; ++i)
319 fn = entityfieldname(i);
320 ft = entityfieldtype(i);
321 next = i * '1 0 0' + ft * '0 1 0' + '0 0 1';
322 prev = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", fn)));
325 db_put(TemporaryDB, strcat("/target_spawn/field/", fn), vtos(next));
326 if(fn == "target_spawn_spawnfunc")
327 target_spawn_spawnfunc_field = i;
331 target_spawn_initialized = 1;
335 spawnfunc(target_spawn)
337 initialize_field_db();
338 self.use = target_spawn_use;
339 self.message = strzone(strreplace("'", "\"", self.message));
340 self.target_spawn_id = ++target_spawn_count;
341 InitializeEntity(self, target_spawn_spawnfirst, INITPRIO_LAST);