]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/triggers/triggers.qc
Remove .move_* fields and MOVETYPE_PUSH logic (doesn't work)
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / triggers.qc
1 void SUB_DontUseTargets(entity this, entity actor, entity trigger) { }
2
3 void SUB_UseTargets(entity this, entity actor, entity trigger);
4
5 void DelayThink(entity this)
6 {
7         SUB_UseTargets (this, this.enemy, NULL);
8         remove(this);
9 }
10
11 void FixSize(entity e)
12 {
13         e.mins_x = rint(e.mins_x);
14         e.mins_y = rint(e.mins_y);
15         e.mins_z = rint(e.mins_z);
16
17         e.maxs_x = rint(e.maxs_x);
18         e.maxs_y = rint(e.maxs_y);
19         e.maxs_z = rint(e.maxs_z);
20 }
21
22 #ifdef SVQC
23
24 void trigger_init(entity this)
25 {
26         string m = this.model;
27         EXACTTRIGGER_INIT;
28         if(m != "")
29         {
30                 precache_model(m);
31                 _setmodel(this, m); // no precision needed
32         }
33         setorigin(this, this.origin);
34         if(this.scale)
35                 setsize(this, this.mins * this.scale, this.maxs * this.scale);
36         else
37                 setsize(this, this.mins, this.maxs);
38
39         BITSET_ASSIGN(this.effects, EF_NODEPTHTEST);
40 }
41
42 void trigger_link(entity this, bool(entity this, entity to, int sendflags) sendfunc)
43 {
44         setSendEntity(this, sendfunc);
45         this.SendFlags = 0xFFFFFF;
46 }
47
48 void trigger_common_write(entity this, bool withtarget)
49 {
50         int f = 0;
51         if(this.warpzone_isboxy)
52                 BITSET_ASSIGN(f, 1);
53         if(this.origin != '0 0 0')
54                 BITSET_ASSIGN(f, 4);
55         WriteByte(MSG_ENTITY, f);
56
57         if(withtarget)
58         {
59                 WriteString(MSG_ENTITY, this.target);
60                 WriteString(MSG_ENTITY, this.target2);
61                 WriteString(MSG_ENTITY, this.target3);
62                 WriteString(MSG_ENTITY, this.target4);
63                 WriteString(MSG_ENTITY, this.targetname);
64                 WriteString(MSG_ENTITY, this.killtarget);
65         }
66
67         if(f & 4)
68         {
69                 WriteCoord(MSG_ENTITY, this.origin.x);
70                 WriteCoord(MSG_ENTITY, this.origin.y);
71                 WriteCoord(MSG_ENTITY, this.origin.z);
72         }
73
74         WriteShort(MSG_ENTITY, this.modelindex);
75         WriteCoord(MSG_ENTITY, this.mins.x);
76         WriteCoord(MSG_ENTITY, this.mins.y);
77         WriteCoord(MSG_ENTITY, this.mins.z);
78         WriteCoord(MSG_ENTITY, this.maxs.x);
79         WriteCoord(MSG_ENTITY, this.maxs.y);
80         WriteCoord(MSG_ENTITY, this.maxs.z);
81         WriteByte(MSG_ENTITY, bound(1, this.scale * 16, 255));
82
83         WriteCoord(MSG_ENTITY, this.movedir_x);
84         WriteCoord(MSG_ENTITY, this.movedir_y);
85         WriteCoord(MSG_ENTITY, this.movedir_z);
86
87         WriteCoord(MSG_ENTITY, this.angles_x);
88         WriteCoord(MSG_ENTITY, this.angles_y);
89         WriteCoord(MSG_ENTITY, this.angles_z);
90 }
91
92 #elif defined(CSQC)
93
94 void trigger_common_read(entity this, bool withtarget)
95 {
96         int f = ReadByte();
97         this.warpzone_isboxy = (f & 1);
98
99         if(withtarget)
100         {
101                 if(this.target) { strunzone(this.target); }
102                 this.target = strzone(ReadString());
103                 if(this.target2) { strunzone(this.target2); }
104                 this.target2 = strzone(ReadString());
105                 if(this.target3) { strunzone(this.target3); }
106                 this.target3 = strzone(ReadString());
107                 if(this.target4) { strunzone(this.target4); }
108                 this.target4 = strzone(ReadString());
109                 if(this.targetname) { strunzone(this.targetname); }
110                 this.targetname = strzone(ReadString());
111                 if(this.killtarget) { strunzone(this.killtarget); }
112                 this.killtarget = strzone(ReadString());
113         }
114
115         if(f & 4)
116         {
117                 this.origin_x = ReadCoord();
118                 this.origin_y = ReadCoord();
119                 this.origin_z = ReadCoord();
120         }
121         else
122                 this.origin = '0 0 0';
123         setorigin(this, this.origin);
124
125         this.modelindex = ReadShort();
126         this.mins_x = ReadCoord();
127         this.mins_y = ReadCoord();
128         this.mins_z = ReadCoord();
129         this.maxs_x = ReadCoord();
130         this.maxs_y = ReadCoord();
131         this.maxs_z = ReadCoord();
132         this.scale = ReadByte() / 16;
133         setsize(this, this.mins, this.maxs);
134
135         this.movedir_x = ReadCoord();
136         this.movedir_y = ReadCoord();
137         this.movedir_z = ReadCoord();
138
139         this.angles_x = ReadCoord();
140         this.angles_y = ReadCoord();
141         this.angles_z = ReadCoord();
142 }
143
144 void trigger_remove_generic(entity this)
145 {
146         if(this.target) { strunzone(this.target); }
147         this.target = string_null;
148
149         if(this.target2) { strunzone(this.target2); }
150         this.target2 = string_null;
151
152         if(this.target3) { strunzone(this.target3); }
153         this.target3 = string_null;
154
155         if(this.target4) { strunzone(this.target4); }
156         this.target4 = string_null;
157
158         if(this.targetname) { strunzone(this.targetname); }
159         this.target = string_null;
160
161         if(this.killtarget) { strunzone(this.killtarget); }
162         this.killtarget = string_null;
163 }
164 #endif
165
166 /*
167 ==============================
168 SUB_UseTargets
169
170 the global "activator" should be set to the entity that initiated the firing.
171
172 If this.delay is set, a DelayedUse entity will be created that will actually
173 do the SUB_UseTargets after that many seconds have passed.
174
175 Centerprints any this.message to the activator.
176
177 Removes all entities with a targetname that match this.killtarget,
178 and removes them, so some events can remove other triggers.
179
180 Search for (string)targetname in all entities that
181 match (string)this.target and call their .use function
182
183 ==============================
184 */
185 void SUB_UseTargets(entity this, entity actor, entity trigger)
186 {
187 //
188 // check for a delay
189 //
190         if (this.delay)
191         {
192         // create a temp object to fire at a later time
193                 entity t = new(DelayedUse);
194                 t.nextthink = time + this.delay;
195                 setthink(t, DelayThink);
196                 t.enemy = actor;
197                 t.message = this.message;
198                 t.killtarget = this.killtarget;
199                 t.target = this.target;
200                 t.target2 = this.target2;
201                 t.target3 = this.target3;
202                 t.target4 = this.target4;
203                 return;
204         }
205
206         string s;
207
208 //
209 // print the message
210 //
211 #ifdef SVQC
212         if(this)
213         if(IS_PLAYER(actor) && this.message != "")
214         if(IS_REAL_CLIENT(actor))
215         {
216                 centerprint(actor, this.message);
217                 if (this.noise == "")
218                         play2(actor, SND(TALK));
219         }
220
221 //
222 // kill the killtagets
223 //
224         s = this.killtarget;
225         if (s != "")
226         {
227                 for(entity t = NULL; (t = find(t, targetname, s)); )
228                         remove(t);
229         }
230 #endif
231
232 //
233 // fire targets
234 //
235
236         if(this.target_random)
237                 RandomSelection_Init();
238
239         for(int i = 0; i < 4; ++i)
240         {
241                 switch(i)
242                 {
243                         default:
244                         case 0: s = this.target; break;
245                         case 1: s = this.target2; break;
246                         case 2: s = this.target3; break;
247                         case 3: s = this.target4; break;
248                 }
249                 if (s != "")
250                 {
251                         // Flag to set func_clientwall state
252                         // 1 == deactivate, 2 == activate, 0 == do nothing
253                         int aw_flag = this.antiwall_flag;
254                         for(entity t = NULL; (t = find(t, targetname, s)); )
255                         {
256                                 if(t.use)
257                                 {
258                                         if(this.target_random)
259                                         {
260                                                 RandomSelection_Add(t, 0, string_null, 1, 0);
261                                         }
262                                         else
263                                         {
264                                                 if (t.classname == "func_clientwall" || t.classname == "func_clientillusionary")
265                                                         t.antiwall_flag = aw_flag;
266
267                                                 t.use(t, actor, this);
268                                         }
269                                 }
270                         }
271                 }
272         }
273
274         if(this.target_random && RandomSelection_chosen_ent)
275                 RandomSelection_chosen_ent.use(RandomSelection_chosen_ent, actor, this);
276 }
277
278 void SUB_UseTargets_self(entity this)
279 {
280         SUB_UseTargets(this, NULL, NULL);
281 }