2 // "classname" "target_spawn"
\r
3 // "message" "fieldname value fieldname value ..."
\r
5 // 1 = call the spawn function
\r
6 // 2 = trigger on map load
\r
8 float target_spawn_initialized;
\r
9 .void() target_spawn_spawnfunc;
\r
10 float target_spawn_spawnfunc_field;
\r
11 .entity target_spawn_activator;
\r
12 .float target_spawn_id;
\r
13 float target_spawn_count;
\r
15 void target_spawn_helper_setmodel()
\r
17 setmodel(self, self.model);
\r
20 void target_spawn_helper_setsize()
\r
22 setsize(self, self.mins, self.maxs);
\r
25 void target_spawn_useon(entity e)
\r
27 float i, n, valuefieldpos;
\r
28 string key, value, valuefield, valueoffset, valueoffsetrandom;
\r
32 entity oldactivator;
\r
33 entity kt, t2, t3, t4;
\r
35 n = tokenize_console(self.message);
\r
36 self.target_spawn_activator = activator;
\r
38 kt = find(world, targetname, self.killtarget);
\r
39 t2 = find(world, targetname, self.target2);
\r
40 t3 = find(world, targetname, self.target3);
\r
41 t4 = find(world, targetname, self.target4);
\r
43 for(i = 0; i < n-1; i += 2)
\r
50 data_y = FIELD_STRING;
\r
54 data = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", key)));
\r
55 if(data_y == 0) // undefined field, i.e., invalid type
\r
57 print("target_spawn: invalid/unknown entity key ", key, " specified, ignored!\n");
\r
61 if(substring(value, 0, 1) == "$")
\r
63 value = substring(value, 1, strlen(value) - 1);
\r
64 if(substring(value, 0, 1) == "$")
\r
66 // deferred replacement
\r
68 // useful for creating target_spawns with this!
\r
73 valuefieldpos = strstrofs(value, "+", 0);
\r
75 if(valuefieldpos != -1)
\r
77 valueoffset = substring(value, valuefieldpos + 1, strlen(value) - valuefieldpos - 1);
\r
78 value = substring(value, 0, valuefieldpos);
\r
81 valuefieldpos = strstrofs(valueoffset, "+", 0);
\r
82 valueoffsetrandom = "";
\r
83 if(valuefieldpos != -1)
\r
85 valueoffsetrandom = substring(valueoffset, valuefieldpos + 1, strlen(valueoffset) - valuefieldpos - 1);
\r
86 valueoffset = substring(valueoffset, 0, valuefieldpos);
\r
89 valuefieldpos = strstrofs(value, ".", 0);
\r
91 if(valuefieldpos != -1)
\r
93 valuefield = substring(value, valuefieldpos + 1, strlen(value) - valuefieldpos - 1);
\r
94 value = substring(value, 0, valuefieldpos);
\r
102 else if(value == "activator")
\r
104 valueent = activator;
\r
107 else if(value == "other")
\r
112 else if(value == "pusher")
\r
114 if(time < activator.pushltime)
\r
115 valueent = activator.pusher;
\r
120 else if(value == "target")
\r
125 else if(value == "killtarget")
\r
130 else if(value == "target2")
\r
135 else if(value == "target3")
\r
140 else if(value == "target4")
\r
145 else if(value == "time")
\r
148 value = ftos(time);
\r
152 print("target_spawn: invalid/unknown variable replacement ", value, " specified, ignored!\n");
\r
156 if(valuefield == "")
\r
159 value = ftos(num_for_edict(valueent));
\r
165 print("target_spawn: try to get a field of a non-entity, ignored!\n");
\r
168 data2 = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", valuefield)));
\r
169 if(data2_y == 0) // undefined field, i.e., invalid type
\r
171 print("target_spawn: invalid/unknown entity key replacement ", valuefield, " specified, ignored!\n");
\r
174 value = getentityfieldstring(data2_x, valueent);
\r
177 if(valueoffset != "")
\r
182 value = strcat(value, valueoffset);
\r
185 value = ftos(stof(value) + stof(valueoffset));
\r
188 value = vtos(stov(value) + stov(valueoffset));
\r
191 print("target_spawn: only string, float and vector fields can do calculations, calculation ignored!\n");
\r
196 if(valueoffsetrandom != "")
\r
201 value = ftos(stof(value) + random() * stof(valueoffsetrandom));
\r
204 data2 = stov(valueoffsetrandom);
\r
205 value = vtos(stov(value) + random() * data2_x * '1 0 0' + random() * data2_y * '0 1 0' + random() * data2_z * '0 0 1');
\r
208 print("target_spawn: only float and vector fields can do random calculations, calculation ignored!\n");
\r
216 if(substring(value, 0, 1) == "_")
\r
217 value = strcat("target_spawn_helper", value);
\r
218 putentityfieldstring(target_spawn_spawnfunc_field, e, value);
\r
221 oldactivator = activator;
\r
224 activator = oldself.target_spawn_activator;
\r
226 self.target_spawn_spawnfunc();
\r
229 activator = oldactivator;
\r
233 if(data_y == FIELD_VECTOR)
\r
234 value = strreplace("'", "", value); // why?!?
\r
235 putentityfieldstring(data_x, e, value);
\r
240 float target_spawn_cancreate()
\r
246 if(c == 0) // no limit?
\r
249 ++c; // increase count to not include MYSELF
\r
250 for(e = world; (e = findfloat(e, target_spawn_id, self.target_spawn_id)); --c)
\r
253 // if c now is 0, we have AT LEAST the given count (maybe more), so don't spawn any more
\r
259 void target_spawn_use()
\r
263 if(self.target == "")
\r
265 // spawn new entity
\r
266 if(!target_spawn_cancreate())
\r
269 target_spawn_useon(e);
\r
270 e.target_spawn_id = self.target_spawn_id;
\r
275 for(e = world; (e = find(e, targetname, self.target)); )
\r
276 target_spawn_useon(e);
\r
280 void target_spawn_spawnfirst()
\r
282 activator = self.target_spawn_activator;
\r
283 if(self.spawnflags & 2)
\r
284 target_spawn_use();
\r
287 void initialize_field_db()
\r
289 if(!target_spawn_initialized)
\r
296 n = numentityfields();
\r
297 for(i = 0; i < n; ++i)
\r
299 fn = entityfieldname(i);
\r
300 ft = entityfieldtype(i);
\r
301 new = i * '1 0 0' + ft * '0 1 0' + '0 0 1';
\r
302 prev = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", fn)));
\r
305 db_put(TemporaryDB, strcat("/target_spawn/field/", fn), vtos(new));
\r
306 if(fn == "target_spawn_spawnfunc")
\r
307 target_spawn_spawnfunc_field = i;
\r
311 target_spawn_initialized = 1;
\r
315 void spawnfunc_target_spawn()
\r
317 initialize_field_db();
\r
318 self.use = target_spawn_use;
\r
319 self.message = strzone(strreplace("'", "\"", self.message));
\r
320 self.target_spawn_id = ++target_spawn_count;
\r
321 InitializeEntity(self, target_spawn_spawnfirst, INITPRIO_LAST);
\r
325 void trigger_relay_if_use()
\r
330 // TODO make this generic AND faster than nextent()ing through all, if somehow possible
\r
331 n = (cvar_string(self.netname) == cvar_string(self.message));
\r
332 if(self.spawnflags & 1)
\r
339 void spawnfunc_trigger_relay_if()
\r
341 self.use = trigger_relay_if_use;
\r