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 strfree(this.target);
120 strfree(this.target2);
121 strfree(this.target3);
122 strfree(this.target4);
123 strfree(this.targetname);
124 strfree(this.killtarget);
126 int targbits = ReadByte();
128 this.target = ((targbits & BIT(0)) ? strzone(ReadString()) : string_null);
129 this.target2 = ((targbits & BIT(1)) ? strzone(ReadString()) : string_null);
130 this.target3 = ((targbits & BIT(2)) ? strzone(ReadString()) : string_null);
131 this.target4 = ((targbits & BIT(3)) ? strzone(ReadString()) : string_null);
132 this.targetname = ((targbits & BIT(4)) ? strzone(ReadString()) : string_null);
133 this.killtarget = ((targbits & BIT(5)) ? strzone(ReadString()) : string_null);
137 this.origin = ReadVector();
139 this.origin = '0 0 0';
140 setorigin(this, this.origin);
143 this.movedir = ReadVector();
145 this.movedir = '0 0 0';
148 this.angles = ReadVector();
150 this.angles = '0 0 0';
152 this.modelindex = ReadShort();
153 this.mins = ReadVector();
154 this.maxs = ReadVector();
155 this.scale = ReadByte() / 16;
156 setsize(this, this.mins, this.maxs);
159 void trigger_remove_generic(entity this)
161 strfree(this.target);
162 strfree(this.target2);
163 strfree(this.target3);
164 strfree(this.target4);
165 strfree(this.targetname);
166 strfree(this.killtarget);
172 ==============================
175 the global "activator" should be set to the entity that initiated the firing.
177 If this.delay is set, a DelayedUse entity will be created that will actually
178 do the SUB_UseTargets after that many seconds have passed.
180 Centerprints any this.message to the activator.
182 Removes all entities with a targetname that match this.killtarget,
183 and removes them, so some events can remove other triggers.
185 Search for (string)targetname in all entities that
186 match (string)this.target and call their .use function
188 ==============================
191 void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventReuse)
198 // create a temp object to fire at a later time
199 entity t = new(DelayedUse);
200 t.nextthink = time + this.delay;
201 setthink(t, DelayThink);
203 t.message = this.message;
204 t.killtarget = this.killtarget;
205 t.target = this.target;
206 t.target2 = this.target2;
207 t.target3 = this.target3;
208 t.target4 = this.target4;
209 t.antiwall_flag = this.antiwall_flag;
220 if(IS_PLAYER(actor) && this.message != "")
221 if(IS_REAL_CLIENT(actor))
223 centerprint(actor, this.message);
224 if (this.noise == "")
225 play2(actor, SND(TALK));
229 // kill the killtagets
234 for(entity t = NULL; (t = find(t, targetname, s)); )
243 if(this.target_random)
244 RandomSelection_Init();
246 for(int i = 0; i < 4; ++i)
251 case 0: s = this.target; break;
252 case 1: s = this.target2; break;
253 case 2: s = this.target3; break;
254 case 3: s = this.target4; break;
258 // Flag to set func_clientwall state
259 // 1 == deactivate, 2 == activate, 0 == do nothing
260 int aw_flag = this.antiwall_flag;
261 for(entity t = NULL; (t = find(t, targetname, s)); )
263 if(t.use && (t.sub_target_used != time || !preventReuse))
265 if(this.target_random)
267 RandomSelection_AddEnt(t, 1, 0);
271 if (t.classname == "func_clientwall" || t.classname == "func_clientillusionary")
272 t.antiwall_flag = aw_flag;
274 t.use(t, actor, this);
276 t.sub_target_used = time;
283 if(this.target_random && RandomSelection_chosen_ent)
285 RandomSelection_chosen_ent.use(RandomSelection_chosen_ent, actor, this);
287 RandomSelection_chosen_ent.sub_target_used = time;
291 void SUB_UseTargets(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, false); }
292 void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, true); }