]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/gamec/t_plats.c
renamed nullfunction to SUB_Null and gave it a definition to hush compiler warnings
[divverent/nexuiz.git] / qcsrc / gamec / t_plats.c
1 void() plat_center_touch;
2 void() plat_outside_touch;
3 void() plat_trigger_use;
4 void() plat_go_up;
5 void() plat_go_down;
6 void() plat_crush;
7 float PLAT_LOW_TRIGGER = 1;
8
9 void() plat_spawn_inside_trigger =
10 {
11         local entity trigger;
12         local vector tmin, tmax;
13
14         trigger = spawn();
15         trigger.touch = plat_center_touch;
16         trigger.movetype = MOVETYPE_NONE;
17         trigger.solid = SOLID_TRIGGER;
18         trigger.enemy = self;
19
20         tmin = self.mins + '25 25 0';
21         tmax = self.maxs - '25 25 -8';
22         tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
23         if (self.spawnflags & PLAT_LOW_TRIGGER)
24                 tmax_z = tmin_z + 8;
25
26         if (self.size_x <= 50)
27         {
28                 tmin_x = (self.mins_x + self.maxs_x) / 2;
29                 tmax_x = tmin_x + 1;
30         }
31         if (self.size_y <= 50)
32         {
33                 tmin_y = (self.mins_y + self.maxs_y) / 2;
34                 tmax_y = tmin_y + 1;
35         }
36
37         setsize (trigger, tmin, tmax);
38 };
39
40 void() plat_hit_top =
41 {
42         sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
43         self.state = 1;
44         self.think = plat_go_down;
45         self.nextthink = self.ltime + 3;
46 };
47
48 void() plat_hit_bottom =
49 {
50         sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
51         self.state = 2;
52 };
53
54 void() plat_go_down =
55 {
56         sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
57         self.state = 3;
58         SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom);
59 };
60
61 void() plat_go_up =
62 {
63         sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
64         self.state = 4;
65         SUB_CalcMove (self.pos1, self.speed, plat_hit_top);
66 };
67
68 void() plat_center_touch =
69 {
70         if (other.classname != "player")
71                 return;
72
73         if (other.health <= 0)
74                 return;
75
76         self = self.enemy;
77         if (self.state == 2)
78                 plat_go_up ();
79         else if (self.state == 1)
80                 self.nextthink = self.ltime + 1;        // delay going down
81 };
82
83 void() plat_outside_touch =
84 {
85         if (other.classname != "player")
86                 return;
87
88         if (other.health <= 0)
89                 return;
90
91         self = self.enemy;
92         if (self.state == 1)
93                 plat_go_down ();
94 };
95
96 void() plat_trigger_use =
97 {
98         if (self.think)
99                 return;         // allready activated
100         plat_go_down();
101 };
102
103
104 void() plat_crush =
105 {
106         if (self.state == 4)
107                 plat_go_down ();
108         else if (self.state == 3)
109                 plat_go_up ();
110         else
111                 objerror ("plat_crush: bad self.state\n");
112 };
113
114 void() plat_use =
115 {
116         self.use = SUB_Null;
117         if (self.state != 4)
118                 objerror ("plat_use: not in up state");
119         plat_go_down();
120 };
121
122
123 .string sound1, sound2;
124
125 void() func_plat =
126 {
127         if (!self.t_length)
128                 self.t_length = 80;
129         if (!self.t_width)
130                 self.t_width = 10;
131
132         if (self.sounds == 0)
133                 self.sounds = 2;
134
135         if (self.sounds == 1)
136         {
137                 precache_sound ("plats/plat1.wav");
138                 precache_sound ("plats/plat2.wav");
139                 self.noise = "plats/plat1.wav";
140                 self.noise1 = "plats/plat2.wav";
141         }
142
143         if (self.sounds == 2)
144         {
145                 precache_sound ("plats/medplat1.wav");
146                 precache_sound ("plats/medplat2.wav");
147                 self.noise = "plats/medplat1.wav";
148                 self.noise1 = "plats/medplat2.wav";
149         }
150
151         if (self.sound1)
152         {
153                 precache_sound (self.sound1);
154                 self.noise = self.sound1;
155         }
156         if (self.sound2)
157         {
158                 precache_sound (self.sound2);
159                 self.noise1 = self.sound2;
160         }
161
162         self.mangle = self.angles;
163         self.angles = '0 0 0';
164
165         self.classname = "plat";
166         self.solid = SOLID_BSP;
167         self.movetype = MOVETYPE_PUSH;
168         setorigin (self, self.origin);
169         setmodel (self, self.model);
170         setsize (self, self.mins , self.maxs);
171
172         self.blocked = plat_crush;
173         if (!self.speed)
174                 self.speed = 150;
175         self.pos1 = self.origin;
176         self.pos2 = self.origin;
177         self.pos2_z = self.origin_z - self.size_z + 8;
178
179         self.use = plat_trigger_use;
180
181         plat_spawn_inside_trigger ();   // the "start moving" trigger
182
183         if (self.targetname)
184         {
185                 self.state = 4;
186                 self.use = plat_use;
187         }
188         else
189         {
190                 setorigin (self, self.pos2);
191                 self.state = 2;
192         }
193 };
194
195
196 /*
197 void() train_next;
198 void() func_train_find;
199
200 void() train_blocked =
201 {
202         if (time < self.attack_finished)
203                 return;
204         self.attack_finished = time + 0.5;
205 };
206 void() train_use =
207 {
208         if (self.think != func_train_find)
209                 return;
210         train_next();
211 };
212
213 void() train_wait =
214 {
215         if (self.wait)
216         {
217                 self.nextthink = self.ltime + self.wait;
218                 sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
219         }
220         else
221                 self.nextthink = self.ltime + 0.1;
222
223         self.think = train_next;
224 };
225
226 void() train_next =
227 {
228         local entity targ;
229
230         targ = find (world, targetname, self.target);
231         self.target = targ.target;
232         if (!self.target)
233                 objerror ("train_next: no next target");
234         if (targ.wait)
235                 self.wait = targ.wait;
236         else
237                 self.wait = 0;
238         sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
239         SUB_CalcMove (targ.origin - self.mins, self.speed, train_wait);
240 };
241
242 void() func_train_find =
243 {
244         local entity targ;
245
246         targ = find (world, targetname, self.target);
247         self.target = targ.target;
248         setorigin (self, targ.origin - self.mins);
249         if (!self.targetname)
250         {       // not triggered, so start immediately
251                 self.nextthink = self.ltime + 0.1;
252                 self.think = train_next;
253         }
254 };
255
256
257 void() func_train =
258 {
259         if (!self.speed)
260                 self.speed = 100;
261         if (!self.target)
262                 objerror ("func_train without a target");
263
264         if (self.sounds == 0)
265         {
266                 self.noise = ("misc/null.wav");
267                 precache_sound ("misc/null.wav");
268                 self.noise1 = ("misc/null.wav");
269                 precache_sound ("misc/null.wav");
270         }
271
272         if (self.sounds == 1)
273         {
274                 self.noise = ("plats/train2.wav");
275                 precache_sound ("plats/train2.wav");
276                 self.noise1 = ("plats/train1.wav");
277                 precache_sound ("plats/train1.wav");
278         }
279
280         self.solid = SOLID_BSP;
281         self.movetype = MOVETYPE_PUSH;
282         self.blocked = train_blocked;
283         self.use = train_use;
284         self.classname = "train";
285
286         setmodel (self, self.model);
287         setsize (self, self.mins , self.maxs);
288         setorigin (self, self.origin);
289         self.nextthink = self.ltime + 0.1;
290         self.think = func_train_find;
291 };
292 */
293
294 void() train_next;
295 void() train_wait =
296 {
297         self.think = train_next;
298         self.nextthink = self.ltime + self.wait;
299 };
300
301 void() train_next =
302 {
303         local entity targ;
304         targ = find(world, targetname, self.target);
305         self.target = targ.target;
306         if (!self.target)
307                 objerror("train_next: no next target");
308         self.wait = targ.wait;
309         if (!self.wait)
310                 self.wait = 0.1;
311         if (targ.speed)
312                 SUB_CalcMove(targ.origin - self.mins, targ.speed, train_wait);
313         else
314                 SUB_CalcMove(targ.origin - self.mins, self.speed, train_wait);
315 };
316
317 void() func_train_find =
318 {
319         local entity targ;
320         targ = find(world, targetname, self.target);
321         self.target = targ.target;
322         setorigin(self, targ.origin - self.mins);
323         self.nextthink = self.ltime + 1;
324         self.think = train_next;
325 };
326
327 /*QUAKED func_train (0 .5 .8) ?
328 Ridable platform, targets path_corner path to follow.
329 speed : speed the train moves (can be overridden by each path_corner)
330 target : targetname of first path_corner (starts here)
331 */
332 void() func_train =
333 {
334         if (!self.target)
335                 objerror("func_train without a target");
336         if (!self.speed)
337                 self.speed = 100;
338
339         self.solid = SOLID_BSP;
340         self.movetype = MOVETYPE_PUSH;
341
342         setmodel(self, self.model);
343         setsize(self, self.mins, self.maxs);
344         setorigin(self, self.origin);
345
346         // wait for targets to spawn
347         self.nextthink = self.ltime + 0.1;
348         self.think = func_train_find;
349 };
350
351 /*QUAKED func_rotating (0 .5 .8) ? - - X_AXIS Y_AXIS
352 Brush model that spins in place on one axis (default Z).
353 speed : speed to rotate (in degrees per second)
354 noise : path/name of looping .wav file to play.
355 */
356 void() func_rotating =
357 {
358         if (self.noise)
359         {
360                 precache_sound(self.noise);
361                 ambientsound(self.origin, self.noise, 1, ATTN_IDLE);
362         }
363         if (!self.speed)
364                 self.speed = 100;
365         // FIXME: test if this turns the right way, then remove this comment (negate as needed)
366         if (self.spawnflags & 4) // X (untested)
367                 self.avelocity = '0 0 1' * self.speed;
368         // FIXME: test if this turns the right way, then remove this comment (negate as needed)
369         else if (self.spawnflags & 8) // Y (untested)
370                 self.avelocity = '1 0 0' * self.speed;
371         // FIXME: test if this turns the right way, then remove this comment (negate as needed)
372         else // Z
373                 self.avelocity = '0 1 0' * self.speed;
374
375         self.solid = SOLID_BSP;
376         self.movetype = MOVETYPE_PUSH;
377
378         setmodel(self, self.model);
379         setsize(self, self.mins, self.maxs);
380         setorigin(self, self.origin);
381
382         // wait for targets to spawn
383         self.nextthink = self.ltime + 999999999;
384         self.think = SUB_Null;
385 };
386
387 .float height;
388 .float phase;
389 void() func_bobbing_controller_think =
390 {
391         local vector v;
392         self.nextthink = time + 0.1;
393         // calculate sinewave using makevectors
394         makevectors((time * self.owner.cnt + self.owner.phase) * '0 1 0');
395         v = self.owner.destvec + self.owner.movedir * v_forward_y;
396         // * 10 so it will arrive in 0.1 sec
397         self.owner.velocity = (v - self.owner.origin) * 10;
398 };
399
400 /*QUAKED func_bobbing (0 .5 .8) ? X_AXIS Y_AXIS
401 Brush model that moves back and forth on one axis (default Z).
402 speed : how long one cycle takes in seconds (default 4)
403 height : how far the cycle moves (default 32)
404 phase : cycle timing adjustment (0-1 as a fraction of the cycle, default 0)
405 noise : path/name of looping .wav file to play.
406 */
407 void() func_bobbing =
408 {
409         local entity controller;
410         if (self.noise)
411         {
412                 precache_sound(self.noise);
413                 ambientsound(self.origin, self.noise, 1, ATTN_IDLE);
414         }
415         if (!self.speed)
416                 self.speed = 4;
417         if (!self.height)
418                 self.height = 32;
419         // center of bobbing motion
420         self.destvec = self.origin;
421         // time scale to get degrees
422         self.cnt = 360 / self.speed;
423         // how far to bob
424         if (self.spawnflags & 1) // X
425                 self.movedir = '1 0 0' * self.height;
426         else if (self.spawnflags & 2) // Y
427                 self.movedir = '0 1 0' * self.height;
428         else // Z
429                 self.movedir = '0 0 1' * self.height;
430
431         self.solid = SOLID_BSP;
432         self.movetype = MOVETYPE_PUSH;
433
434         setmodel(self, self.model);
435         setsize(self, self.mins, self.maxs);
436         setorigin(self, self.origin);
437
438         // wait for targets to spawn
439         controller = spawn();
440         controller.classname = "func_bobbing_controller";
441         controller.owner = self;
442         controller.nextthink = time + 1;
443         controller.think = func_bobbing_controller_think;
444         self.nextthink = self.ltime + 999999999;
445         self.think = SUB_Null;
446 };