]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/tturrets/units/unit_walker.qc
add SUB_Friction (currently only used by target_spawn)
[divverent/nexuiz.git] / data / qcsrc / server / tturrets / units / unit_walker.qc
1 #define ANIM_NO 0\r
2 #define ANIM_WALK 1\r
3 #define ANIM_RUN 1.1\r
4 #define ANIM_STRAFE_L 2\r
5 #define ANIM_STRAFE_R 3\r
6 #define ANIM_TURN 2\r
7 #define ANIM_JUMP 4\r
8 #define ANIM_LAND 5\r
9 #define ANIM_PAIN 6\r
10 #define ANIM_MEELE 7\r
11 .float animflag;\r
12 \r
13 .entity wkr_props;\r
14 .entity wkr_spawn;\r
15 \r
16 #define WALKER_MIN '-70 -70 5'\r
17 #define WALKER_MAX '70 70 70'\r
18 \r
19 /*\r
20 .entity goalcurrent, goalstack01, goalstack02, goalstack03;\r
21 .entity goalstack04, goalstack05, goalstack06, goalstack07;\r
22 .entity goalstack08, goalstack09, goalstack10, goalstack11;\r
23 .entity goalstack12, goalstack13, goalstack14, goalstack15;\r
24 .entity goalstack16, goalstack17, goalstack18, goalstack19;\r
25 .entity goalstack20, goalstack21, goalstack22, goalstack23;\r
26 .entity goalstack24, goalstack25, goalstack26, goalstack27;\r
27 .entity goalstack28, goalstack29, goalstack30, goalstack31;\r
28 */\r
29 \r
30 float walker_firecheck()\r
31 {\r
32     if (!turret_stdproc_firecheck()) return 0;\r
33     //if(self.tur_cannon.frame != 0) return 0;\r
34 \r
35     //if(self.walking  == 1) self.walking = 2;\r
36     //if(self.walking != 0)\r
37     //    return 0;\r
38 \r
39     return 1;\r
40 }\r
41 \r
42 void walker_meele_dmg()\r
43 {\r
44     vector where;\r
45     entity e;\r
46 \r
47     makevectors(self.angles);\r
48     where = self.origin + v_forward * 128;\r
49 \r
50     e = findradius(where,80);\r
51     while(e)\r
52     {\r
53         if(turret_validate_target(self,e,self.target_validate_flags))\r
54             if(e != self)\r
55                 Damage(e,self,self,cvar("g_turrets_unit_walker_std_meele_dmg "),DEATH_TURRET,'0 0 0', v_forward * cvar("g_turrets_unit_walker_std_meele_force") );\r
56 \r
57         e = e.chain;\r
58     }\r
59 }\r
60 \r
61 void walker_animate()\r
62 {\r
63 \r
64     if(self.tur_head.frame != 0)\r
65         self.tur_head.frame = self.tur_head.frame +1;\r
66 \r
67     if(self.tur_head.frame > 12)\r
68         self.tur_head.frame = 0;\r
69 \r
70 \r
71     switch(self.animflag)\r
72     {\r
73         case ANIM_NO:\r
74             //if(self.frame != 0)\r
75             //    self.frame = 0;\r
76         break;\r
77 \r
78         case ANIM_WALK:\r
79             self.frame = self.frame + 1;\r
80             if(self.frame > 25)\r
81                 self.frame = 5;\r
82         break;\r
83 \r
84         case ANIM_RUN:\r
85             self.frame = self.frame + 2;\r
86             if(self.frame > 25)\r
87                 self.frame = 5;\r
88         break;\r
89 \r
90         case ANIM_STRAFE_L:\r
91             if(self.frame < 35) self.frame = 35;\r
92             self.frame = self.frame + 1;\r
93             if(self.frame > 55) self.frame = 35;\r
94         break;\r
95 \r
96         case ANIM_STRAFE_R:\r
97             if(self.frame < 65) self.frame = 65;\r
98             self.frame = self.frame + 1;\r
99             if(self.frame > 85) self.frame = 65;\r
100         break;\r
101 \r
102         case ANIM_JUMP:\r
103             if(self.frame < 95) self.frame = 95;\r
104             if(self.frame > 100)\r
105             self.frame = self.frame + 1;\r
106 \r
107         break;\r
108 \r
109         case ANIM_LAND:\r
110             if(self.frame < 100) self.frame = 100;\r
111             self.frame = self.frame + 1;\r
112             if(self.frame > 107)\r
113                 self.animflag = ANIM_NO;\r
114         break;\r
115 \r
116         case ANIM_PAIN:\r
117             if(self.frame < 90) self.frame = 90;\r
118             self.frame = self.frame + 1;\r
119             if(self.frame > 95)\r
120                 self.animflag = ANIM_NO;\r
121         break;\r
122 \r
123         case ANIM_MEELE:\r
124             if(self.frame < 123) self.frame = 123;\r
125             self.frame = self.frame + 1;\r
126 \r
127             if(self.frame == 133)\r
128                 walker_meele_dmg();\r
129 \r
130             if(self.frame > 140)\r
131                 self.animflag = ANIM_NO;\r
132 \r
133     }\r
134 }\r
135 \r
136 \r
137 \r
138 \r
139 \r
140 void walker_rocket_explode()\r
141 {\r
142     vector org2;\r
143 \r
144     sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", 1, ATTN_NORM);\r
145     org2 = findbetterlocation (self.origin, 16);\r
146 \r
147     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);\r
148     WriteByte (MSG_BROADCAST, 78);\r
149     WriteCoord (MSG_BROADCAST, org2_x);\r
150     WriteCoord (MSG_BROADCAST, org2_y);\r
151     WriteCoord (MSG_BROADCAST, org2_z);\r
152 \r
153     self.event_damage = SUB_Null;\r
154 \r
155     RadiusDamage (self, self.owner, cvar("g_turrets_unit_walker_std_rocket_dmg"), 0, cvar("g_turrets_unit_walker_std_rocket_radius"), world, cvar("g_turrets_unit_walker_std_rocket_force"), DEATH_TURRET, world);\r
156 \r
157     remove (self);\r
158 }\r
159 \r
160 void walker_rocket_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)\r
161 {\r
162     self.health = self.health - damage;\r
163     self.velocity = self.velocity + vforce;\r
164     if (self.health <= 0) walker_rocket_explode();\r
165 }\r
166 \r
167 \r
168 /*\r
169 g_turrets_unit_walker_std_rocket_refire\r
170 g_turrets_unit_walker_std_rocket_dmg\r
171 g_turrets_unit_walker_std_rocket_radius\r
172 g_turrets_unit_walker_std_rocket_force\r
173 g_turrets_unit_walker_std_rocket_tunrate\r
174 g_turrets_unit_walker_std_rocket_speed\r
175 g_turrets_unit_walker_std_rocket_speed_add\r
176 */\r
177 \r
178 void walker_rocket_loop();\r
179 void walker_rocket_think()\r
180 {\r
181     vector olddir,newdir;\r
182     float edist;\r
183     float itime;\r
184     float m_speed;\r
185 \r
186     self.nextthink          = time + 0.1;\r
187 \r
188     olddir = normalize(self.velocity);\r
189     edist = vlen(self.enemy.origin - self.origin);\r
190 \r
191     // Simulate crudely guidance\r
192     if(self.cnt < time)\r
193     {\r
194         if(edist < 1000)\r
195             self.tur_shotorg = randomvec() * min(edist,64);\r
196         else\r
197             self.tur_shotorg = randomvec() * min(edist,256);\r
198         self.cnt = time + 0.5;\r
199     }\r
200     if(edist < 256)\r
201         self.tur_shotorg = '0 0 0';\r
202 \r
203 \r
204     if (self.tur_health < time)\r
205     {\r
206         self.think = walker_rocket_explode;\r
207         self.nextthink = time;\r
208         return;\r
209     }\r
210 \r
211     if((random() < 0.01) && (self.shot_dmg != 1337))\r
212     {\r
213         walker_rocket_loop();\r
214         return;\r
215     }\r
216 \r
217     olddir = normalize(self.velocity);\r
218 \r
219     // Accelerate\r
220     m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");\r
221 \r
222     // Enemy dead? just keep on the current heading then.\r
223     if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))\r
224     {\r
225 \r
226         // Make sure we dont return to tracking a respawned player\r
227         self.enemy = world;\r
228 \r
229         // Turn model\r
230         self.angles = vectoangles(self.velocity);\r
231     }\r
232 \r
233     if (self.enemy)\r
234     {\r
235         // Predict enemy position\r
236         itime = max(edist / m_speed,1);\r
237         newdir = normalize((self.enemy.origin + self.tur_shotorg) - self.origin);\r
238     }\r
239     else\r
240     {\r
241         //pre_pos = self.origin + olddir;\r
242         newdir  = olddir;\r
243     }\r
244 \r
245     // Turn\r
246     newdir = normalize(olddir + newdir * cvar("g_turrets_unit_walker_std_rocket_tunrate"));\r
247 \r
248     self.velocity = newdir * m_speed;\r
249 \r
250     // Turn model\r
251     self.angles = vectoangles(self.velocity);\r
252 \r
253     if (time+itime < time+0.1)\r
254     {\r
255         self.think = turret_hellion_missile_explode;\r
256         self.nextthink = time + itime;\r
257     }\r
258 }\r
259 \r
260 void walker_rocket_loop3()\r
261 {\r
262     self.nextthink = time + 0.1;\r
263     if(vlen(self.origin - self.tur_shotorg) < 128 )\r
264     {\r
265         self.think = walker_rocket_think;\r
266         return;\r
267     }\r
268 \r
269     vector newdir;\r
270     vector olddir;\r
271     float m_speed;\r
272 \r
273     m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");\r
274 \r
275     olddir = normalize(self.velocity);\r
276 \r
277 \r
278     newdir = normalize(self.tur_shotorg  - self.origin);\r
279 \r
280     newdir = normalize(olddir + newdir * cvar("g_turrets_unit_walker_std_rocket_tunrate"));\r
281 \r
282 \r
283     self.velocity = newdir * m_speed;\r
284     self.angles = vectoangles(self.velocity);\r
285 }\r
286 \r
287 void walker_rocket_loop2()\r
288 {\r
289     self.nextthink = time + 0;\r
290 \r
291     if(vlen(self.origin - self.tur_shotorg) < 128 )\r
292     {\r
293         self.tur_shotorg = self.origin - '0 0 200';\r
294         self.think = walker_rocket_loop3;\r
295         return;\r
296     }\r
297 \r
298     vector newdir;\r
299     vector olddir;\r
300     float m_speed;\r
301 \r
302     m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");\r
303 \r
304     olddir = normalize(self.velocity);\r
305 \r
306     newdir = normalize(self.tur_shotorg  - self.origin);\r
307 \r
308     newdir = normalize(olddir + newdir * cvar("g_turrets_unit_walker_std_rocket_tunrate"));\r
309 \r
310     self.velocity = newdir * m_speed;\r
311 \r
312     self.angles = vectoangles(self.velocity);\r
313 \r
314 }\r
315 \r
316 void walker_rocket_loop()\r
317 {\r
318 \r
319     self.nextthink= time + 0;\r
320 \r
321     self.tur_shotorg = self.origin + '0 0 400';\r
322 \r
323     self.think = walker_rocket_loop2;\r
324 \r
325     self.shot_dmg = 1337;\r
326 }\r
327 \r
328 \r
329 \r
330 void walker_fire_rocket(vector org)\r
331 {\r
332 \r
333     entity rocket;\r
334 \r
335 \r
336     //self.angles_x *= -1;\r
337     makevectors(self.angles);\r
338     //self.angles_x *= -1;\r
339 \r
340     rocket = spawn ();\r
341     setorigin(rocket, org);\r
342 \r
343     sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", 1, ATTN_NORM);\r
344     sound (rocket, CHAN_PROJECTILE, "weapons/rocket_fly.wav", 0.4, ATTN_NORM);\r
345     setmodel (rocket, "models/turrets/rocket.md3"); // precision set below\r
346     setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot\r
347 \r
348     rocket.classname          = "walker_rocket";\r
349     rocket.owner              = self;\r
350     rocket.bot_dodge          = TRUE;\r
351     rocket.bot_dodgerating    = 50;\r
352     rocket.takedamage         = DAMAGE_YES;\r
353 \r
354     rocket.damageforcescale   = 2;\r
355     rocket.health             = 10;\r
356     rocket.tur_shotorg        = randomvec() * 512;\r
357     rocket.cnt                = time + 1;\r
358     rocket.enemy              = self.enemy;\r
359 \r
360     if(random() < 0.01)\r
361         rocket.think          = walker_rocket_loop;\r
362     else\r
363         rocket.think          = walker_rocket_think;\r
364 \r
365     rocket.nextthink          = time + 0.2;\r
366     rocket.solid              = SOLID_BBOX;\r
367     rocket.movetype           = MOVETYPE_FLYMISSILE;\r
368     rocket.effects            = EF_LOWPRECISION;\r
369     rocket.velocity           = ((v_forward + v_up * 0.5) +(randomvec() * 0.15))* cvar("g_turrets_unit_walker_std_rocket_speed");\r
370     rocket.angles             = vectoangles(rocket.velocity);\r
371     rocket.touch              = walker_rocket_explode;\r
372     rocket.flags              = FL_PROJECTILE;\r
373     rocket.solid              = SOLID_BBOX;\r
374     rocket.tur_health         = time + 9;\r
375 \r
376     te_explosion (rocket.origin);\r
377 \r
378 }\r
379 \r
380 #define s_turn 10\r
381 #define s_walk 100\r
382 #define s_run 300\r
383 #define s_accel1 8\r
384 #define s_accel2 16\r
385 #define s_decel 8\r
386 \r
387 void rv_think()\r
388 {\r
389     float f;\r
390     vector org;\r
391 \r
392     self.cnt = self.cnt -1;\r
393     if(self.cnt < 0)\r
394     {\r
395         remove(self);\r
396         return;\r
397     }\r
398 \r
399     if(self.cnt> 1)\r
400         f = gettagindex(self.owner,"tag_rocket01");\r
401     else\r
402         f = gettagindex(self.owner,"tag_rocket02");\r
403 \r
404     org = self.owner.origin + gettaginfo(self.owner,f);\r
405 \r
406 \r
407     self.nextthink = time + 0.2;\r
408 \r
409     self = self.owner;\r
410     walker_fire_rocket(org);\r
411 }\r
412 \r
413 void walker_postthink()\r
414 {\r
415     vector wish_angle;\r
416     vector real_angle;\r
417     float turn_limit;\r
418 \r
419 \r
420 \r
421     if(self.flags & FL_ONGROUND)\r
422     {\r
423         self.animflag = ANIM_NO;\r
424     }\r
425 \r
426     if(self.enemy)\r
427     {\r
428         if(self.tur_head.attack_finished_single < time)\r
429         {\r
430             entity rv;\r
431             rv = spawn();\r
432             rv.think = rv_think;\r
433             rv.nextthink = time;\r
434             rv.cnt = 4;\r
435             rv.owner = self;\r
436 \r
437             self.tur_head.attack_finished_single = time + cvar("g_turrets_unit_walker_std_rocket_refire");\r
438         }\r
439 \r
440     }\r
441 \r
442     if(self.goalcurrent)\r
443     {\r
444         //if(self.enemy && (self.tur_dist_enemy < self.target_range_fire))\r
445         //   self.animflag = ANIM_TURN;\r
446         //else\r
447         //{\r
448             if(vlen(self.origin  - self.goalcurrent.origin) < 64)\r
449                 if(self.goalcurrent.goalcurrent == world)\r
450                     self.goalcurrent = world; // Path endpoint reached, go roaming.\r
451                 else\r
452                     self.goalcurrent = self.goalcurrent.goalcurrent;\r
453 \r
454             self.animflag = ANIM_WALK;\r
455         //}\r
456 \r
457 \r
458     }\r
459     else // Roaming mode\r
460     {\r
461 \r
462         if(self.enemy)\r
463         {\r
464             wish_angle = angleofs(self,self.enemy); //normalize(self.origin-self.enemy.origin);\r
465 \r
466             if(self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_meele_range"))\r
467             {\r
468 \r
469                 if(fabs(wish_angle_y) < 15)\r
470                     self.animflag = ANIM_MEELE;\r
471             }\r
472             else\r
473             {\r
474                 if(fabs(wish_angle_y) < 15)\r
475                     self.animflag = ANIM_RUN;\r
476                 else if(fabs(wish_angle_y) < 30)\r
477                     self.animflag = ANIM_WALK;\r
478                 else\r
479                     self.animflag = ANIM_TURN;\r
480             }\r
481 \r
482         }\r
483         else\r
484             self.animflag = ANIM_NO;\r
485     }\r
486 \r
487 \r
488     float s_speed;\r
489 \r
490     s_speed = vlen(self.velocity);\r
491 \r
492     // Turn on the spot\r
493     if (self.animflag == ANIM_TURN) {\r
494         if(self.enemy)\r
495             wish_angle = normalize(self.enemy.origin - self.origin);\r
496         else\r
497             wish_angle = normalize(self.goalcurrent.origin - self.origin);        wish_angle = vectoangles(wish_angle);                  // And make a angle\r
498 \r
499         real_angle = wish_angle - self.angles;\r
500 \r
501         if (real_angle_x < 0) real_angle_x += 360;\r
502         if (real_angle_x > 180) real_angle_x -= 360;\r
503 \r
504         if (real_angle_y < 0) real_angle_y += 360;\r
505         if (real_angle_y > 180) real_angle_y -= 360;\r
506 \r
507         turn_limit = cvar("g_turrets_unit_walker_turn_turnrate");\r
508         // Convert from dgr/sec to dgr/tic\r
509         turn_limit  = turn_limit / (1 / self.ticrate);\r
510 \r
511         //real_angle_x = bound((-1 * turn_limit),real_angle_x, turn_limit);\r
512         real_angle_y = bound((-1 * turn_limit),real_angle_y, turn_limit);\r
513 \r
514         self.angles_y = self.angles_y + real_angle_y;\r
515 \r
516         if(self.enemy)\r
517             v_forward = normalize(self.enemy.origin - self.origin);\r
518         else\r
519             v_forward = normalize(self.goalcurrent.origin - self.origin);\r
520 \r
521         makevectors(self.angles);\r
522 \r
523         if(s_speed > s_turn)\r
524             self.velocity = (v_forward * max((s_speed - s_decel),s_turn));\r
525         if(s_speed < s_turn)\r
526             self.velocity = (v_forward * min((s_speed + s_accel1),s_turn));\r
527     }\r
528     else if (self.animflag == ANIM_WALK) // Gg walking\r
529     {\r
530         if(self.goalcurrent)\r
531             wish_angle = normalize(self.goalcurrent.origin - self.origin);\r
532         else\r
533             if(self.enemy)\r
534                 wish_angle = normalize(self.enemy.origin - self.origin);\r
535             else\r
536                 wish_angle = self.angles;\r
537 \r
538 \r
539         wish_angle = vectoangles(wish_angle);                  // And make a angle\r
540         real_angle = wish_angle - self.angles;\r
541 \r
542         if (real_angle_x < 0) real_angle_x += 360;\r
543         if (real_angle_x > 180) real_angle_x -= 360;\r
544 \r
545         if (real_angle_y < 0) real_angle_y += 360;\r
546         if (real_angle_y > 180) real_angle_y -= 360;\r
547 \r
548         turn_limit = cvar("g_turrets_unit_walker_walk_turnrate");\r
549         // Convert from dgr/sec to dgr/tic\r
550         turn_limit  = turn_limit / (1 / self.ticrate);\r
551 \r
552         //real_angle_x = bound((-1 * turn_limit),real_angle_x, turn_limit);\r
553         real_angle_y = bound((-1 * turn_limit),real_angle_y, turn_limit);\r
554 \r
555         self.angles_y = self.angles_y + real_angle_y;\r
556 \r
557         if(self.goalcurrent)\r
558             v_forward = normalize(self.goalcurrent.origin - self.origin);\r
559         else\r
560             if(self.enemy)\r
561                 v_forward = normalize(self.enemy.origin - self.origin);\r
562 \r
563         makevectors(self.angles);\r
564         //self.velocity = v_forward * s_walk;\r
565 \r
566         //if(self.flags & FL_ONGROUND)\r
567         {\r
568             if(s_speed > s_walk)\r
569                 self.velocity = (v_forward * max((s_speed - s_decel),s_walk));\r
570             if(s_speed <= s_walk)\r
571                 self.velocity = (v_forward * min((s_speed + s_accel1),s_walk));\r
572         }\r
573 \r
574 \r
575     }\r
576     else if (self.animflag == ANIM_RUN) // Move fast, turn slow\r
577     {\r
578         if(self.goalcurrent)\r
579             wish_angle = normalize(self.goalcurrent.origin - self.origin);\r
580         else\r
581             if(self.enemy)\r
582                 wish_angle = normalize(self.enemy.origin - self.origin);\r
583             else\r
584                 wish_angle = self.angles;\r
585 \r
586         wish_angle = vectoangles(wish_angle);                  // And make a angle\r
587         real_angle = wish_angle - self.angles;\r
588 \r
589         if (real_angle_x < 0) real_angle_x += 360;\r
590         if (real_angle_x > 180) real_angle_x -= 360;\r
591 \r
592         if (real_angle_y < 0) real_angle_y += 360;\r
593         if (real_angle_y > 180) real_angle_y -= 360;\r
594 \r
595         turn_limit = cvar("g_turrets_unit_walker_run_turnrate");\r
596         // Convert from dgr/sec to dgr/tic\r
597         turn_limit  = turn_limit / (1 / self.ticrate);\r
598 \r
599         //real_angle_x = bound((-1 * turn_limit),real_angle_x, turn_limit);\r
600         real_angle_y = bound((-1 * turn_limit),real_angle_y, turn_limit);\r
601 \r
602         self.angles_y = self.angles_y + real_angle_y;\r
603 \r
604 \r
605         if(self.enemy)\r
606             v_forward = normalize(self.enemy.origin - self.origin);\r
607         else\r
608             v_forward = normalize(self.goalcurrent.origin - self.origin);\r
609 \r
610         makevectors(self.angles);\r
611 \r
612         if(self.flags & FL_ONGROUND)\r
613         {\r
614             if(s_speed > s_run)\r
615                 self.velocity = (v_forward * max((s_speed - s_decel),s_run));\r
616             if(s_speed <= s_run)\r
617                 self.velocity = (v_forward * min((s_speed + s_accel2),s_run));\r
618         }\r
619     } else {\r
620 \r
621         if(self.flags & FL_ONGROUND)\r
622         {\r
623             makevectors(self.angles);\r
624             if(s_speed > 0)\r
625                 self.velocity = min(s_speed - s_decel,0) * v_forward;\r
626         }\r
627     }\r
628 \r
629 \r
630 \r
631     walker_animate();\r
632 \r
633 \r
634 }\r
635 \r
636 void walker_attack()\r
637 {\r
638     entity flash;\r
639 \r
640     //turret_do_updates(self);\r
641 \r
642     self.tur_head.frame = self.tur_head.frame + 1;\r
643 \r
644     sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", 1, ATTN_NORM);\r
645 \r
646 \r
647     fireBullet (self.tur_shotorg_updated, self.tur_shotdir_updated,self.shot_spread, self.shot_dmg, self.shot_force, DEATH_TURRET, FALSE);\r
648 \r
649     te_smallflash(self.tur_shotorg_updated);\r
650 \r
651     if(!(self.uzi_bulletcounter & 3))\r
652     {\r
653 \r
654         trailparticles(self,particleeffectnum("EF_MGTURRETTRAIL"),self.tur_shotorg_updated,trace_endpos);\r
655         // te_lightning1(self,self.tur_shotorg_updated,trace_endpos);\r
656         flash = spawn();\r
657         setmodel(flash, "models/uziflash.md3"); // precision set below\r
658         setattachment(flash, self.tur_head, "tag_fire");\r
659         flash.scale = 3;\r
660         flash.think = W_Uzi_Flash_Go;\r
661         flash.nextthink = time + 0.02;\r
662         flash.frame = 2;\r
663         flash.angles_z = flash.v_angle_z + random() * 180;\r
664         flash.alpha = 1;\r
665         flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;\r
666     }\r
667 \r
668     self.uzi_bulletcounter = self.uzi_bulletcounter + 1;\r
669 }\r
670 \r
671 void walker_respawnhook()\r
672 {\r
673     vector vtmp;\r
674     self.origin = self.wkr_spawn.origin;\r
675     self.wkr_props.solid = SOLID_BBOX;\r
676     self.wkr_props.alpha = 1;\r
677 \r
678     self.angles = self.wkr_spawn.angles;\r
679     vtmp = self.origin;\r
680     vtmp_z +=self.wkr_spawn.origin_z + self.wkr_spawn.maxs_z;\r
681     setorigin(self,vtmp);\r
682 \r
683 }\r
684 void walker_diehook()\r
685 {\r
686     self.wkr_props.solid = SOLID_NOT;\r
687     self.wkr_props.alpha = -1;\r
688 }\r
689 \r
690 //.string target_start;\r
691 void turret_walker_dinit()\r
692 {\r
693     entity e;\r
694 \r
695     if (self.netname == "")      self.netname     = "Walker Turret";\r
696 \r
697     if(self.target != "")\r
698     {\r
699         e = find(world,targetname,self.target);\r
700         if(!e)\r
701         {\r
702             bprint("Warning! initital waypoint for Walker does NOT exsist!\n");\r
703             self.target = "";\r
704 \r
705             //remove(self);\r
706             //return;\r
707         }\r
708 \r
709         if(e.classname != "walker_checkpoint")\r
710             dprint("Warning: not a walker path\n");\r
711         else\r
712             self.goalcurrent = e;\r
713     }\r
714 \r
715 \r
716 \r
717 \r
718     self.wkr_props = spawn();\r
719     self.wkr_spawn = spawn();\r
720 \r
721     self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;\r
722     self.turrcaps_flags = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_ROAM | TFL_TURRCAPS_LINKED;\r
723     self.aim_flags = TFL_AIM_LEAD | TFL_AIM_ZEASE;\r
724 \r
725     self.turret_respawnhook = walker_respawnhook;\r
726     self.turret_diehook = walker_diehook;\r
727 \r
728     self.ticrate = 0.05;\r
729     if (turret_stdproc_init("walker_std") == 0)\r
730     {\r
731         remove(self);\r
732         return;\r
733     }\r
734     // self.scale = 1.5;\r
735     //setsize(self,'38 38 55','-38 -38 1');\r
736 \r
737     self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;\r
738     self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;\r
739 \r
740     //self.flags      = FL_CLIENT;\r
741     self.iscreature = TRUE;\r
742     self.movetype   = MOVETYPE_WALK;\r
743     self.solid      = SOLID_BBOX;// SOLID_SLIDEBOX;\r
744     self.takedamage = DAMAGE_AIM;\r
745 \r
746     setmodel(self.wkr_props,"models/turrets/walker_props.md3");\r
747     setmodel(self.wkr_spawn,"models/turrets/walker_spawn.md3");\r
748     setorigin(self.wkr_spawn,self.origin);\r
749 \r
750     self.wkr_spawn.angles   = self.angles;\r
751     self.wkr_spawn.solid    = SOLID_NOT;\r
752 \r
753     traceline(self.wkr_spawn.origin + '0 0 10', self.wkr_spawn.origin - '0 0 10000', MOVE_NOMONSTERS, self);\r
754     setorigin(self.wkr_spawn,trace_endpos + '0 0 4');\r
755 \r
756     setmodel(self,"models/turrets/walker_body.md3");\r
757     setmodel(self.tur_head,"models/turrets/walker_head_minigun.md3");\r
758 \r
759     setattachment(self.tur_head,self,"tag_head");\r
760     setattachment(self.wkr_props,self,"tag_head");\r
761 \r
762     vector v;\r
763     float f;\r
764     f = gettagindex(self.tur_head,"tag_fire");\r
765     v = gettaginfo(self.tur_head,f);\r
766     v_y = v_y * -1;\r
767 \r
768     setsize(self,WALKER_MIN,WALKER_MAX);\r
769     //setsize(self,'-70 -70 0','70 70 55');\r
770 \r
771     self.tur_shotorg = v;\r
772     self.tur_aimorg  = v;\r
773 \r
774     self.idle_aim = '0 0 0';\r
775 \r
776 //    self.v_home = self.origin;\r
777 \r
778     self.turret_firecheckfunc   = walker_firecheck;\r
779 \r
780     // Our fire routine\r
781     self.turret_firefunc  = walker_attack;\r
782 \r
783     self.turret_postthink = walker_postthink;\r
784 \r
785 }\r
786 \r
787 \r
788 void spawnfunc_turret_walker()\r
789 {\r
790     precache_model ("models/turrets/walker_head_minigun.md3");\r
791     precache_model ("models/turrets/walker_body.md3");\r
792     precache_model ("models/turrets/walker_props.md3");\r
793     precache_model ("models/turrets/walker_spawn.md3");\r
794     precache_model ( "models/turrets/rocket.md3");\r
795 \r
796     self.think = turret_walker_dinit;\r
797     self.nextthink = time + 0.5;\r
798 }\r