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