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 WriteVector(MSG_ENTITY, this.mins);
106 WriteVector(MSG_ENTITY, this.maxs);
107 WriteByte(MSG_ENTITY, bound(1, this.scale * 16, 255));
112 void trigger_common_read(entity this, bool withtarget)
115 this.warpzone_isboxy = (f & 1);
119 if(this.target) { strunzone(this.target); }
120 if(this.target2) { strunzone(this.target2); }
121 if(this.target3) { strunzone(this.target3); }
122 if(this.target4) { strunzone(this.target4); }
123 if(this.targetname) { strunzone(this.targetname); }
124 if(this.killtarget) { strunzone(this.killtarget); }
126 int targbits = ReadByte();
128 #define X(xs,b) MACRO_BEGIN { \
129 if(targbits & BIT(b)) \
130 xs = strzone(ReadString()); \
139 X(this.targetname, 4);
140 X(this.killtarget, 5);
145 this.origin = ReadVector();
147 this.origin = '0 0 0';
148 setorigin(this, this.origin);
151 this.movedir = ReadVector();
153 this.movedir = '0 0 0';
156 this.angles = ReadVector();
158 this.angles = '0 0 0';
160 this.modelindex = ReadShort();
161 this.mins = ReadVector();
162 this.maxs = ReadVector();
163 this.scale = ReadByte() / 16;
164 setsize(this, this.mins, this.maxs);
167 void trigger_remove_generic(entity this)
169 if(this.target) { strunzone(this.target); }
170 this.target = string_null;
172 if(this.target2) { strunzone(this.target2); }
173 this.target2 = string_null;
175 if(this.target3) { strunzone(this.target3); }
176 this.target3 = string_null;
178 if(this.target4) { strunzone(this.target4); }
179 this.target4 = string_null;
181 if(this.targetname) { strunzone(this.targetname); }
182 this.target = string_null;
184 if(this.killtarget) { strunzone(this.killtarget); }
185 this.killtarget = string_null;
191 ==============================
194 the global "activator" should be set to the entity that initiated the firing.
196 If this.delay is set, a DelayedUse entity will be created that will actually
197 do the SUB_UseTargets after that many seconds have passed.
199 Centerprints any this.message to the activator.
201 Removes all entities with a targetname that match this.killtarget,
202 and removes them, so some events can remove other triggers.
204 Search for (string)targetname in all entities that
205 match (string)this.target and call their .use function
207 ==============================
210 void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventReuse)
217 // create a temp object to fire at a later time
218 entity t = new(DelayedUse);
219 t.nextthink = time + this.delay;
220 setthink(t, DelayThink);
222 t.message = this.message;
223 t.killtarget = this.killtarget;
224 t.target = this.target;
225 t.target2 = this.target2;
226 t.target3 = this.target3;
227 t.target4 = this.target4;
228 t.antiwall_flag = this.antiwall_flag;
239 if(IS_PLAYER(actor) && this.message != "")
240 if(IS_REAL_CLIENT(actor))
242 centerprint(actor, this.message);
243 if (this.noise == "")
244 play2(actor, SND(TALK));
248 // kill the killtagets
253 for(entity t = NULL; (t = find(t, targetname, s)); )
262 if(this.target_random)
263 RandomSelection_Init();
265 for(int i = 0; i < 4; ++i)
270 case 0: s = this.target; break;
271 case 1: s = this.target2; break;
272 case 2: s = this.target3; break;
273 case 3: s = this.target4; break;
277 // Flag to set func_clientwall state
278 // 1 == deactivate, 2 == activate, 0 == do nothing
279 int aw_flag = this.antiwall_flag;
280 for(entity t = NULL; (t = find(t, targetname, s)); )
282 if(t.use && (t.sub_target_used != time || !preventReuse))
284 if(this.target_random)
286 RandomSelection_AddEnt(t, 1, 0);
290 if (t.classname == "func_clientwall" || t.classname == "func_clientillusionary")
291 t.antiwall_flag = aw_flag;
293 t.use(t, actor, this);
295 t.sub_target_used = time;
302 if(this.target_random && RandomSelection_chosen_ent)
304 RandomSelection_chosen_ent.use(RandomSelection_chosen_ent, actor, this);
306 RandomSelection_chosen_ent.sub_target_used = time;
310 void SUB_UseTargets(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, false); }
311 void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, true); }