2 void SUB_DontUseTargets(entity this, entity actor, entity trigger) { }
4 void SUB_UseTargets(entity this, entity actor, entity trigger);
6 void DelayThink(entity this)
8 SUB_UseTargets (this, this.enemy, NULL);
12 void FixSize(entity e)
14 e.mins_x = rint(e.mins_x);
15 e.mins_y = rint(e.mins_y);
16 e.mins_z = rint(e.mins_z);
18 e.maxs_x = rint(e.maxs_x);
19 e.maxs_y = rint(e.maxs_y);
20 e.maxs_z = rint(e.maxs_z);
25 bool autocvar_g_triggers_debug = true;
27 void trigger_init(entity this)
29 string m = this.model;
31 if(autocvar_g_triggers_debug)
36 _setmodel(this, m); // no precision needed
38 setorigin(this, this.origin);
40 setsize(this, this.mins * this.scale, this.maxs * this.scale);
42 setsize(this, this.mins, this.maxs);
45 if(autocvar_g_triggers_debug)
46 BITSET_ASSIGN(this.effects, EF_NODEPTHTEST);
49 void trigger_link(entity this, bool(entity this, entity to, int sendflags) sendfunc)
51 setSendEntity(this, sendfunc);
52 this.SendFlags = 0xFFFFFF;
55 void trigger_common_write(entity this, bool withtarget)
58 if(this.warpzone_isboxy)
60 if(this.origin != '0 0 0')
62 if(this.movedir != '0 0 0')
64 if(this.angles != '0 0 0')
66 WriteByte(MSG_ENTITY, f);
70 // probably some way to clean this up...
72 if(this.target && this.target != "") targbits |= BIT(0);
73 if(this.target2 && this.target2 != "") targbits |= BIT(1);
74 if(this.target3 && this.target3 != "") targbits |= BIT(2);
75 if(this.target4 && this.target4 != "") targbits |= BIT(3);
76 if(this.targetname && this.targetname != "") targbits |= BIT(4);
77 if(this.killtarget && this.killtarget != "") targbits |= BIT(5);
79 WriteByte(MSG_ENTITY, targbits);
82 WriteString(MSG_ENTITY, this.target);
84 WriteString(MSG_ENTITY, this.target2);
86 WriteString(MSG_ENTITY, this.target3);
88 WriteString(MSG_ENTITY, this.target4);
90 WriteString(MSG_ENTITY, this.targetname);
92 WriteString(MSG_ENTITY, this.killtarget);
96 WriteVector(MSG_ENTITY, this.origin);
99 WriteVector(MSG_ENTITY, this.movedir);
102 WriteVector(MSG_ENTITY, this.angles);
104 WriteShort(MSG_ENTITY, this.modelindex);
105 WriteCoord(MSG_ENTITY, this.mins.x);
106 WriteCoord(MSG_ENTITY, this.mins.y);
107 WriteCoord(MSG_ENTITY, this.mins.z);
108 WriteCoord(MSG_ENTITY, this.maxs.x);
109 WriteCoord(MSG_ENTITY, this.maxs.y);
110 WriteCoord(MSG_ENTITY, this.maxs.z);
111 WriteByte(MSG_ENTITY, bound(1, this.scale * 16, 255));
116 void trigger_common_read(entity this, bool withtarget)
119 this.warpzone_isboxy = (f & 1);
123 if(this.target) { strunzone(this.target); }
124 if(this.target2) { strunzone(this.target2); }
125 if(this.target3) { strunzone(this.target3); }
126 if(this.target4) { strunzone(this.target4); }
127 if(this.targetname) { strunzone(this.targetname); }
128 if(this.killtarget) { strunzone(this.killtarget); }
130 int targbits = ReadByte();
132 #define X(xs,b) MACRO_BEGIN { \
133 if(targbits & BIT(b)) \
134 xs = strzone(ReadString()); \
143 X(this.targetname, 4);
144 X(this.killtarget, 5);
149 this.origin = ReadVector();
151 this.origin = '0 0 0';
152 setorigin(this, this.origin);
155 this.movedir = ReadVector();
157 this.movedir = '0 0 0';
160 this.angles = ReadVector();
162 this.angles = '0 0 0';
164 this.modelindex = ReadShort();
165 this.mins_x = ReadCoord();
166 this.mins_y = ReadCoord();
167 this.mins_z = ReadCoord();
168 this.maxs_x = ReadCoord();
169 this.maxs_y = ReadCoord();
170 this.maxs_z = ReadCoord();
171 this.scale = ReadByte() / 16;
172 setsize(this, this.mins, this.maxs);
175 void trigger_remove_generic(entity this)
177 if(this.target) { strunzone(this.target); }
178 this.target = string_null;
180 if(this.target2) { strunzone(this.target2); }
181 this.target2 = string_null;
183 if(this.target3) { strunzone(this.target3); }
184 this.target3 = string_null;
186 if(this.target4) { strunzone(this.target4); }
187 this.target4 = string_null;
189 if(this.targetname) { strunzone(this.targetname); }
190 this.target = string_null;
192 if(this.killtarget) { strunzone(this.killtarget); }
193 this.killtarget = string_null;
199 ==============================
202 the global "activator" should be set to the entity that initiated the firing.
204 If this.delay is set, a DelayedUse entity will be created that will actually
205 do the SUB_UseTargets after that many seconds have passed.
207 Centerprints any this.message to the activator.
209 Removes all entities with a targetname that match this.killtarget,
210 and removes them, so some events can remove other triggers.
212 Search for (string)targetname in all entities that
213 match (string)this.target and call their .use function
215 ==============================
218 void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventReuse)
225 // create a temp object to fire at a later time
226 entity t = new(DelayedUse);
227 t.nextthink = time + this.delay;
228 setthink(t, DelayThink);
230 t.message = this.message;
231 t.killtarget = this.killtarget;
232 t.target = this.target;
233 t.target2 = this.target2;
234 t.target3 = this.target3;
235 t.target4 = this.target4;
236 t.antiwall_flag = this.antiwall_flag;
247 if(IS_PLAYER(actor) && this.message != "")
248 if(IS_REAL_CLIENT(actor))
250 centerprint(actor, this.message);
251 if (this.noise == "")
252 play2(actor, SND(TALK));
256 // kill the killtagets
261 for(entity t = NULL; (t = find(t, targetname, s)); )
270 if(this.target_random)
271 RandomSelection_Init();
273 for(int i = 0; i < 4; ++i)
278 case 0: s = this.target; break;
279 case 1: s = this.target2; break;
280 case 2: s = this.target3; break;
281 case 3: s = this.target4; break;
285 // Flag to set func_clientwall state
286 // 1 == deactivate, 2 == activate, 0 == do nothing
287 int aw_flag = this.antiwall_flag;
288 for(entity t = NULL; (t = find(t, targetname, s)); )
290 if(t.use && (t.sub_target_used != time || !preventReuse))
292 if(this.target_random)
294 RandomSelection_AddEnt(t, 1, 0);
298 if (t.classname == "func_clientwall" || t.classname == "func_clientillusionary")
299 t.antiwall_flag = aw_flag;
301 t.use(t, actor, this);
303 t.sub_target_used = time;
310 if(this.target_random && RandomSelection_chosen_ent)
312 RandomSelection_chosen_ent.use(RandomSelection_chosen_ent, actor, this);
314 RandomSelection_chosen_ent.sub_target_used = time;
318 void SUB_UseTargets(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, false); }
319 void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, true); }