]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/tturrets/units/unit_walker.qc
Fix warnings
[divverent/nexuiz.git] / data / qcsrc / server / tturrets / units / unit_walker.qc
1 #define ANIM_NO         0\r
2 #define ANIM_REVERSE    1\r
3 #define ANIM_WALK       2\r
4 #define ANIM_RUN        3\r
5 #define ANIM_STRAFE_L   4\r
6 #define ANIM_STRAFE_R   5\r
7 #define ANIM_TURN       6\r
8 #define ANIM_JUMP       7\r
9 #define ANIM_LAND       8\r
10 #define ANIM_PAIN       9\r
11 #define ANIM_MEELE      10\r
12 #define ANIM_SWIM       11\r
13 #define ANIM_ROAM       12\r
14 \r
15 #define WVM_IDLE_UP 25\r
16 #define WVM_IDLE    50\r
17 \r
18 #define WVM_PATH  1000\r
19 #define WVM_ENEMY 2000\r
20 #define WVM_STOP  3000\r
21 #define WVM_DODGE 4000\r
22 #define  WVM_PANIC 10000\r
23 #define walker_verbs_move verbs_move\r
24 \r
25 #define WVA_MINIGUN 100\r
26 #define WVA_ROCKET  500\r
27 #define WVA_MEELE   1000\r
28 #define walker_verbs_attack verbs_attack\r
29 \r
30 #define WVI_IDLE 1\r
31 #define WVI_ROAM 10\r
32 #define walker_verbs_idle verbs_idle\r
33 \r
34 .float animflag;\r
35 .entity wkr_spawn;\r
36 \r
37 #define WALKER_MIN '-70 -70 5'\r
38 #define WALKER_MAX '70 70 70'\r
39 \r
40 #define WALKER_PATH(s,e) pathlib_astar(s,e)\r
41 \r
42 float walker_firecheck()\r
43 {\r
44     if (self.animflag == ANIM_MEELE)\r
45         return 0;\r
46 \r
47     return turret_stdproc_firecheck();\r
48 }\r
49 \r
50 void walker_meele_do_dmg()\r
51 {\r
52     vector where;\r
53     entity e;\r
54     makevectors(self.angles);\r
55     where = self.origin + v_forward * 128;\r
56 \r
57     //w_deathtypestring = "tried to hug the cute spider thingy.";\r
58     e = findradius(where,64);\r
59     while (e)\r
60     {\r
61         if (turret_validate_target(self,e,self.target_validate_flags))\r
62             if (e != self && e.owner != self)\r
63                 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
64 \r
65         e = e.chain;\r
66     }\r
67 }\r
68 \r
69 void walker_animate()\r
70 {\r
71     vector real_angle;\r
72     float  vz;\r
73 \r
74     real_angle = vectoangles(self.steerto) - self.angles;\r
75     vz         = self.velocity_z;\r
76 \r
77     if (self.tur_head.frame != 0)\r
78         self.tur_head.frame = self.tur_head.frame +1;\r
79 \r
80     if (self.tur_head.frame > 12)\r
81         self.tur_head.frame = 0;\r
82 \r
83     switch (self.animflag)\r
84     {\r
85 \r
86     case ANIM_NO:\r
87         if (self.frame != 0)\r
88             self.frame = 0;\r
89 \r
90         movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop"));\r
91 \r
92         break;\r
93 \r
94     case ANIM_REVERSE:\r
95         if ((self.frame < 5) || (self.frame > 25))\r
96             self.frame = 25;\r
97 \r
98         self.frame = self.frame -1;\r
99         movelib_move_simple(v_forward * -1 ,cvar("g_turrets_unit_walker_speed_walk"),0.6);\r
100 \r
101         if (self.frame < 5)\r
102             self.frame = 25;\r
103 \r
104         break;\r
105 \r
106     case ANIM_TURN:\r
107 \r
108         if ((self.frame < 30) || (self.frame > 55))\r
109             self.frame = 30;\r
110 \r
111         self.frame = self.frame + 1;\r
112 \r
113         self.angles_y += bound(-15,shortangle_f(real_angle_y,self.angles_y),15);\r
114 \r
115         movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop"));\r
116 \r
117         if (self.frame > 55)\r
118             self.frame = 35;\r
119 \r
120         break;\r
121 \r
122     case ANIM_WALK:\r
123         if ((self.frame < 5) || (self.frame > 25))\r
124             self.frame = 5;\r
125 \r
126         self.frame = self.frame +1;\r
127         self.angles_y += bound(-10,shortangle_f(real_angle_y,self.angles_y),10);\r
128         movelib_move_simple(v_forward ,cvar("g_turrets_unit_walker_speed_walk"),0.6);\r
129 \r
130         if (self.frame > 25)\r
131             self.frame = 5;\r
132 \r
133         break;\r
134 \r
135     case ANIM_ROAM:\r
136         if ((self.frame < 5) || (self.frame > 25))\r
137             self.frame = 5;\r
138 \r
139         self.frame = self.frame +1;\r
140 \r
141         self.angles_y += bound(-5,shortangle_f(real_angle_y,self.angles_y),5);\r
142 \r
143         movelib_move_simple(v_forward ,cvar("g_turrets_unit_walker_speed_roam"),0.5);\r
144 \r
145         if (self.frame > 25)\r
146             self.frame = 5;\r
147 \r
148         break;\r
149 \r
150     case ANIM_SWIM:\r
151         if ((self.frame < 142) || (self.frame > 151))\r
152             self.frame = 142;\r
153 \r
154         self.frame = self.frame +1;\r
155 \r
156         self.angles_y += bound(-10,shortangle_f(real_angle_y,self.angles_y),10);\r
157         self.angles_x += bound(-10,shortangle_f(real_angle_x,self.angles_x),10);\r
158 \r
159         movelib_move_simple(v_forward, cvar("g_turrets_unit_walker_speed_swim"),0.3);\r
160         vz = self.velocity_z + sin(time * 4) * 8;\r
161 \r
162         if (self.frame > 151)\r
163             self.frame = 146;\r
164 \r
165         break;\r
166 \r
167     case ANIM_RUN:\r
168 \r
169         if ((self.frame < 5) || (self.frame > 25))\r
170             self.frame = 5;\r
171 \r
172         self.angles_y += bound(-5,shortangle_f(real_angle_y,self.angles_y),5);\r
173         movelib_move_simple(v_forward, cvar("g_turrets_unit_walker_speed_run"),0.6);\r
174 \r
175         if (self.frame > 25)\r
176             self.frame = 5;\r
177 \r
178         break;\r
179 \r
180     case ANIM_STRAFE_L:\r
181         if ((self.frame < 30) || (self.frame > 55))\r
182             self.frame = 30;\r
183 \r
184         self.frame = self.frame + 1;\r
185         self.angles_y += bound(-2.5,shortangle_f(real_angle_y,self.angles_y),2.5);\r
186         movelib_move_simple(v_right * -1, cvar("g_turrets_unit_walker_speed_walk"),0.8);\r
187 \r
188         if (self.frame > 55)\r
189             self.frame = 35;\r
190         break;\r
191 \r
192     case ANIM_STRAFE_R:\r
193         if ((self.frame < 60) || (self.frame > 65))\r
194             self.frame = 60;\r
195 \r
196         self.frame = self.frame + 1;\r
197         self.angles_y += bound(-2.5,shortangle_f(real_angle_y,self.angles_y),2.5);\r
198         movelib_move_simple(v_right, cvar("g_turrets_unit_walker_speed_walk"),0.8);\r
199 \r
200         if (self.frame > 85)\r
201             self.frame = 65;\r
202 \r
203         break;\r
204 \r
205     case ANIM_JUMP:\r
206         if ((self.frame < 95) || (self.frame > 100))\r
207             self.frame = 95;\r
208 \r
209         self.velocity += '0 0 1' * cvar("g_turrets_unit_walker_speed_jump");\r
210 \r
211         if (self.frame > 100)\r
212             self.frame = self.frame + 1;\r
213 \r
214         break;\r
215 \r
216     case ANIM_LAND:\r
217         if ((self.frame < 100) || (self.frame > 107))\r
218             self.frame = 100;\r
219 \r
220         self.frame = self.frame + 1;\r
221 \r
222         if (self.frame > 107)\r
223             self.animflag = ANIM_NO;\r
224 \r
225         break;\r
226 \r
227     case ANIM_PAIN:\r
228         if ((self.frame < 60) || (self.frame > 95))\r
229             self.frame = 90;\r
230 \r
231         self.frame = self.frame + 1;\r
232 \r
233         if (self.frame > 95)\r
234             self.animflag = ANIM_NO;\r
235 \r
236         break;\r
237 \r
238     case ANIM_MEELE:\r
239         if ((self.frame < 123) || (self.frame > 140))\r
240             self.frame = 123;\r
241 \r
242         movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop"));\r
243 \r
244         self.frame = self.frame + 2;\r
245 \r
246         if (self.frame == 133)\r
247             walker_meele_do_dmg();\r
248 \r
249         if (self.frame > 140)\r
250         {\r
251             self.animflag = ANIM_NO;\r
252             self.frame = 0;\r
253         }\r
254     }\r
255 \r
256     self.velocity_z = vz;\r
257 \r
258     if (self.flags & FL_ONGROUND)\r
259         movelib_groundalign4point(300,100);\r
260 \r
261 }\r
262 \r
263 \r
264 void walker_rocket_explode()\r
265 {\r
266     vector org2;\r
267 \r
268     if (self.event_damage != SUB_Null)\r
269     {\r
270         self.event_damage = SUB_Null;\r
271         self.think = walker_rocket_explode;\r
272         self.nextthink = time;\r
273         return;\r
274     }\r
275 \r
276     sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);\r
277     org2 = findbetterlocation (self.origin, 16);\r
278 \r
279     pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);\r
280     //w_deathtypestring = "got blasted to oblivion";\r
281     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
282 \r
283     remove (self);\r
284 }\r
285 \r
286 void walker_rocket_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)\r
287 {\r
288     self.health = self.health - damage;\r
289     self.velocity = self.velocity + vforce;\r
290     if (self.health <= 0)\r
291         walker_rocket_explode();\r
292 }\r
293 \r
294 #define WALKER_ROCKET_MOVE movelib_move_simple(newdir,cvar("g_turrets_unit_walker_std_rocket_speed"),cvar("g_turrets_unit_walker_std_rocket_tunrate")); UpdateCSQCProjectile(self)\r
295 void walker_rocket_loop();\r
296 void walker_rocket_think()\r
297 {\r
298     vector newdir;\r
299     float edist;\r
300     float itime;\r
301     float m_speed;\r
302 \r
303     self.nextthink = time;\r
304 \r
305     edist = vlen(self.enemy.origin - self.origin);\r
306 \r
307     // Simulate crude guidance\r
308     if (self.cnt < time)\r
309     {\r
310         if (edist < 1000)\r
311             self.tur_shotorg = randomvec() * min(edist,64);\r
312         else\r
313             self.tur_shotorg = randomvec() * min(edist,256);\r
314 \r
315         self.cnt = time + 0.5;\r
316     }\r
317 \r
318     if (edist < 256)\r
319         self.tur_shotorg = '0 0 0';\r
320 \r
321 \r
322     if (self.tur_health < time)\r
323     {\r
324         self.think = walker_rocket_explode;\r
325         self.nextthink = time;\r
326         return;\r
327     }\r
328 \r
329     if (self.shot_dmg != 1337)\r
330         if (random() < 0.01)\r
331         {\r
332             walker_rocket_loop();\r
333             return;\r
334         }\r
335 \r
336     m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");\r
337 \r
338     // Enemy dead? just keep on the current heading then.\r
339     if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))\r
340     {\r
341         // Make sure we dont return to tracking a respawned player\r
342         self.enemy = world;\r
343     }\r
344 \r
345     if (self.enemy)\r
346     {\r
347         itime = max(edist / m_speed,1);\r
348         newdir = steerlib_pull(self.enemy.origin + self.tur_shotorg);\r
349     }\r
350     else\r
351     {\r
352         newdir  = normalize(self.velocity);\r
353     }\r
354 \r
355     WALKER_ROCKET_MOVE;\r
356 }\r
357 \r
358 void walker_rocket_loop3()\r
359 {\r
360     vector newdir;\r
361     self.nextthink = time;\r
362 \r
363     if (self.tur_health < time)\r
364     {\r
365         self.think = walker_rocket_explode;\r
366         return;\r
367     }\r
368 \r
369     if (vlen(self.origin - self.tur_shotorg) < 128 )\r
370     {\r
371         self.think = walker_rocket_think;\r
372         return;\r
373     }\r
374 \r
375     newdir = steerlib_pull(self.tur_shotorg);\r
376     WALKER_ROCKET_MOVE;\r
377 \r
378     self.angles = vectoangles(self.velocity);\r
379 }\r
380 \r
381 void walker_rocket_loop2()\r
382 {\r
383     vector newdir;\r
384 \r
385     self.nextthink = time;\r
386 \r
387     if (self.tur_health < time)\r
388     {\r
389         self.think = walker_rocket_explode;\r
390         return;\r
391     }\r
392 \r
393     if (vlen(self.origin - self.tur_shotorg) < 128 )\r
394     {\r
395         self.tur_shotorg = self.origin - '0 0 200';\r
396         self.think = walker_rocket_loop3;\r
397         return;\r
398     }\r
399 \r
400     newdir = steerlib_pull(self.tur_shotorg);\r
401     WALKER_ROCKET_MOVE;\r
402 }\r
403 \r
404 void walker_rocket_loop()\r
405 {\r
406     self.nextthink = time;\r
407     self.tur_shotorg = self.origin + '0 0 400';\r
408     self.think = walker_rocket_loop2;\r
409     self.shot_dmg = 1337;\r
410 }\r
411 \r
412 void walker_fire_rocket(vector org)\r
413 {\r
414 \r
415     entity rocket;\r
416 \r
417 \r
418     self.angles_x *= -1;\r
419     makevectors(self.angles);\r
420     self.angles_x *= -1;\r
421 \r
422     te_explosion (org);\r
423 \r
424     rocket = spawn ();\r
425     setorigin(rocket, org);\r
426 \r
427     sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);\r
428     setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot\r
429 \r
430     rocket.classname          = "walker_rocket";\r
431     rocket.owner              = self;\r
432 \r
433     rocket.bot_dodge          = TRUE;\r
434     rocket.bot_dodgerating    = 50;\r
435 \r
436     rocket.takedamage         = DAMAGE_YES;\r
437 \r
438     rocket.damageforcescale   = 2;\r
439     rocket.health             = 25;\r
440     rocket.tur_shotorg        = randomvec() * 512;\r
441     rocket.cnt                = time + 1;\r
442     rocket.enemy              = self.enemy;\r
443 \r
444     if (random() < 0.01)\r
445         rocket.think          = walker_rocket_loop;\r
446     else\r
447         rocket.think          = walker_rocket_think;\r
448 \r
449     rocket.event_damage       = walker_rocket_damage;\r
450 \r
451     rocket.nextthink          = time;// + 0.25;\r
452     rocket.movetype           = MOVETYPE_FLY;\r
453     rocket.velocity           = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * cvar("g_turrets_unit_walker_std_rocket_speed");\r
454     rocket.angles             = vectoangles(rocket.velocity);\r
455     rocket.touch              = walker_rocket_explode;\r
456     rocket.flags              = FL_PROJECTILE;\r
457     rocket.solid              = SOLID_BBOX;\r
458     rocket.tur_health         = time + 9;\r
459 \r
460     CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound\r
461 }\r
462 \r
463 void rv_think()\r
464 {\r
465     float f;\r
466     vector org;\r
467     entity oldself;\r
468 \r
469     if (self.owner.deadflag != DEAD_NO)\r
470     {\r
471         remove(self);\r
472         return;\r
473     }\r
474 \r
475     self.cnt = self.cnt -1;\r
476 \r
477     if (self.cnt < 0)\r
478     {\r
479         remove(self);\r
480         return;\r
481     }\r
482 \r
483     if (self.cnt > 1)\r
484         f = gettagindex(self.owner,"tag_rocket01");\r
485     else\r
486         f = gettagindex(self.owner,"tag_rocket02");\r
487 \r
488     org = gettaginfo(self.owner,f);\r
489 \r
490     self.nextthink = time + 0.2;\r
491     oldself = self;\r
492     self = self.owner;\r
493     walker_fire_rocket(org);\r
494     self = oldself;\r
495 }\r
496 \r
497 float walker_moveverb_path(float eval)\r
498 {\r
499     switch (eval)\r
500     {\r
501     case VCM_EVAL:\r
502 \r
503         if (self.animflag == ANIM_MEELE)\r
504             return VS_CALL_NO;\r
505 \r
506         if (self.pathcurrent)\r
507             return verb.verb_static_value;\r
508 \r
509         return VS_CALL_NO;\r
510 \r
511     case VCM_DO:\r
512         // Do we have a path?\r
513         if not(self.pathcurrent)\r
514         {\r
515             return VS_CALL_NO;\r
516         }\r
517         else\r
518         {\r
519             // Are we close enougth to a path node to switch to the next?\r
520             if (vlen(self.origin  - self.pathcurrent.origin) < 64)\r
521                 if (self.pathcurrent.path_next == world)\r
522                 {\r
523                     // Path endpoint reached\r
524                     pathlib_deletepath(self.pathcurrent.owner);\r
525                     self.pathcurrent = world;\r
526 \r
527                     if (self.pathgoal)\r
528                     {\r
529                         if (self.pathgoal.use)\r
530                             self.pathgoal.use();\r
531 \r
532                         if (self.pathgoal.enemy)\r
533                         {\r
534                             self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin);\r
535                             self.pathgoal = self.pathgoal.enemy;\r
536                         }\r
537                     }\r
538                     else\r
539                         self.pathgoal = world;\r
540                 }\r
541                 else\r
542                     self.pathcurrent = self.pathcurrent.path_next;\r
543         }\r
544 \r
545 \r
546         if (self.pathcurrent)\r
547         {\r
548             switch (self.waterlevel)\r
549             {\r
550             case 0:\r
551                 self.animflag = ANIM_WALK;\r
552             case 1:\r
553             case 2:\r
554                 if (self.animflag == ANIM_WALK)\r
555                     self.animflag = ANIM_WALK;\r
556                 else\r
557                     self.animflag = ANIM_SWIM;\r
558                 break;\r
559             case 3:\r
560                 self.animflag = ANIM_SWIM;\r
561             }\r
562 \r
563             self.moveto = self.pathcurrent.origin;\r
564             self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);\r
565 \r
566             return VS_CALL_YES_DOING;\r
567         }\r
568         else\r
569             return VS_CALL_YES_DONE;\r
570 \r
571     case VCM_REMOVE:\r
572 \r
573         if (self.pathcurrent)\r
574             pathlib_deletepath(self.pathcurrent.owner);\r
575 \r
576         self.pathcurrent = world;\r
577 \r
578         return VS_CALL_YES_DONE;\r
579     }\r
580 \r
581     return VS_CALL_YES_DONE;\r
582 }\r
583 \r
584 float walker_moveverb_enemy(float eval)\r
585 {\r
586     switch (eval)\r
587     {\r
588     case VCM_EVAL:\r
589 \r
590         if (self.animflag == ANIM_MEELE)\r
591             return VS_CALL_NO;\r
592 \r
593         if (self.enemy == world)\r
594             return VS_CALL_NO;\r
595 \r
596         if (tracewalk(self.enemy, self.origin, self.mins, self.maxs, self.enemy.origin, MOVE_NORMAL))\r
597             return verb.verb_static_value;\r
598 \r
599         return VS_CALL_NO;\r
600 \r
601     case VCM_DO:\r
602         switch (self.waterlevel)\r
603         {\r
604         case 0:\r
605             if (self.tur_dist_enemy > 500)\r
606                 self.animflag = ANIM_RUN;\r
607             else\r
608                 self.animflag = ANIM_WALK;\r
609         case 1:\r
610         case 2:\r
611             if (self.animflag != ANIM_SWIM)\r
612                 self.animflag = ANIM_WALK;\r
613             else\r
614                 self.animflag = ANIM_SWIM;\r
615             break;\r
616         case 3:\r
617             self.animflag = ANIM_SWIM;\r
618         }\r
619 \r
620         self.moveto = self.enemy.origin;\r
621         self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);\r
622 \r
623         return VS_CALL_YES_DOING;\r
624     }\r
625 \r
626     return VS_CALL_YES_DONE;\r
627 }\r
628 \r
629 float walker_moveverb_idle_pause(float eval)\r
630 {\r
631     switch (eval)\r
632     {\r
633     case VCM_EVAL:\r
634 \r
635         if (self.animflag == ANIM_MEELE)\r
636             return VS_CALL_NO;\r
637 \r
638         return verb.verb_static_value;\r
639 \r
640     case VCM_DO:\r
641 \r
642         self.moveto   = self.origin;\r
643         self.steerto  = v_forward;\r
644         self.animflag = ANIM_NO;\r
645 \r
646         return VS_CALL_YES_DOING;\r
647     }\r
648 \r
649     return VS_CALL_YES_DONE;\r
650 }\r
651 \r
652 float walker_moveverb_idle_roam(float eval)\r
653 {\r
654     switch (eval)\r
655     {\r
656     case VCM_EVAL:\r
657 \r
658         if (self.animflag == ANIM_MEELE)\r
659             return VS_CALL_NO;\r
660 \r
661         return verb.verb_static_value;\r
662 \r
663     case VCM_DO:\r
664         if(verb.wait < time)\r
665         {\r
666             trace_fraction = 0;\r
667             while(trace_fraction != 1.0)\r
668             {\r
669                 self.moveto = self.origin + (v_forward * 256);\r
670                 self.moveto += v_right * (random() * 256);\r
671                 self.moveto -= v_right * (random() * 256);\r
672 \r
673                 tracebox(self.origin+'0 0 64',self.mins,self.maxs,self.moveto + '0 0 64',MOVE_NORMAL,self);\r
674             }\r
675             verb.wait = time + 10;\r
676         }\r
677         else\r
678         {\r
679             if(verb.wait - time < 9)\r
680                 if(vlen(self.moveto - self.origin) < 32)\r
681                 {\r
682                     verbstack_push(self.walker_verbs_move, walker_moveverb_idle_pause,   WVM_IDLE + WVM_IDLE_UP, random() * (verb.wait - time));\r
683                     self.animflag = ANIM_NO;\r
684                     return VS_CALL_REMOVE;\r
685                 }\r
686         }\r
687 \r
688         self.steerto = steerlib_attract(self.moveto,256);\r
689         te_lightning1(self,self.origin + '0 0 64',self.moveto + '0 0 64');\r
690 \r
691 \r
692 \r
693         switch (self.waterlevel)\r
694         {\r
695         case 0:\r
696             self.animflag = ANIM_ROAM;\r
697         case 1:\r
698         case 2:\r
699             if (self.animflag != ANIM_SWIM)\r
700                 self.animflag = ANIM_ROAM;\r
701 \r
702             break;\r
703         case 3:\r
704             self.animflag = ANIM_SWIM;\r
705         }\r
706 \r
707         return VS_CALL_YES_DOING;\r
708     }\r
709 \r
710     return VS_CALL_YES_DONE;\r
711 }\r
712 \r
713 float walker_moveverb_idle(float eval)\r
714 {\r
715     switch (eval)\r
716     {\r
717     case VCM_EVAL:\r
718 \r
719         if (self.animflag == ANIM_MEELE)\r
720             return VS_CALL_NO;\r
721 \r
722         return verb.verb_static_value;\r
723 \r
724     case VCM_DO:\r
725 \r
726         //if (random() < 0.5)\r
727             verbstack_push(self.walker_verbs_move, walker_moveverb_idle_pause,   WVM_IDLE + WVM_IDLE_UP, random() * 5);\r
728         //else\r
729         //    verbstack_push(self.walker_verbs_move, walker_moveverb_idle_roam,   WVM_IDLE + WVM_IDLE_UP,  random() * 15);\r
730 \r
731         return VS_CALL_YES_DOING;\r
732     }\r
733 \r
734     return VS_CALL_YES_DONE;\r
735 }\r
736 \r
737 float walker_attackverb_meele(float eval)\r
738 {\r
739     switch (eval)\r
740     {\r
741     case VCM_EVAL:\r
742 \r
743         vector wish_angle;\r
744 \r
745         if (cvar("g_turrets_nofire"))\r
746             return VS_CALL_NO;\r
747 \r
748         if (self.animflag == ANIM_SWIM || self.animflag == ANIM_MEELE)\r
749             return VS_CALL_NO;\r
750 \r
751         if (!self.enemy)\r
752             return VS_CALL_NO;\r
753 \r
754         wish_angle = angleofs(self,self.enemy);\r
755 \r
756         if (self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_meele_range"))\r
757             if (fabs(wish_angle_y) < 15)\r
758                 return verb.verb_static_value;\r
759 \r
760         return VS_CALL_NO;\r
761 \r
762     case VCM_DO:\r
763 \r
764         self.moveto   = self.enemy.origin;\r
765         self.steerto  = steerlib_attract2(self.moveto,0.5,500,0.95);\r
766         self.animflag = ANIM_MEELE;\r
767 \r
768         return VS_CALL_YES_DOING;\r
769     }\r
770 \r
771     return VS_CALL_YES_DONE;\r
772 }\r
773 \r
774 float walker_attackverb_rockets(float eval)\r
775 {\r
776     switch (eval)\r
777     {\r
778     case VCM_EVAL:\r
779         if (self.tur_head.attack_finished_single > time)\r
780             return VS_CALL_NO;\r
781 \r
782         if not(self.enemy)\r
783             return VS_CALL_NO;\r
784 \r
785         if (cvar("g_turrets_nofire"))\r
786             return VS_CALL_NO;\r
787 \r
788         if (self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_rockets_range_min"))\r
789             return VS_CALL_NO;\r
790 \r
791         if (self.tur_dist_enemy > cvar("g_turrets_unit_walker_std_rockets_range"))\r
792             return VS_CALL_NO;\r
793 \r
794         return verb.verb_static_value;\r
795 \r
796     case VCM_DO:\r
797 \r
798         entity rv;\r
799 \r
800         rv           = spawn();\r
801         rv.think     = rv_think;\r
802         rv.nextthink = time;\r
803         rv.cnt       = 4;\r
804         rv.owner     = self;\r
805 \r
806         self.tur_head.attack_finished_single = time + cvar("g_turrets_unit_walker_std_rocket_refire");\r
807 \r
808         return VS_CALL_YES_DONE;\r
809     }\r
810 \r
811     return VS_CALL_YES_DONE;\r
812 }\r
813 \r
814 void walker_postthink()\r
815 {\r
816 \r
817     self.angles_x *= -1;\r
818     makevectors(self.angles);\r
819     self.angles_x *= -1;\r
820 \r
821     verbstack_pop(self.walker_verbs_attack);\r
822     verbstack_pop(self.walker_verbs_move);\r
823 \r
824     walker_animate();\r
825 }\r
826 \r
827 void walker_attack()\r
828 {\r
829     entity flash;\r
830 \r
831     //w_deathtypestring = "was miniguned";\r
832     sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM);\r
833     fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, 0, self.shot_force, DEATH_TURRET, 0, 1, cvar("g_balance_uzi_bulletconstant"));\r
834     if (self.uzi_bulletcounter == 2)\r
835     {\r
836 \r
837         flash = spawn();\r
838 \r
839         setmodel(flash, "models/uziflash.md3");\r
840         setattachment(flash, self.tur_head, "tag_fire");\r
841 \r
842         flash.scale     = 3;\r
843         flash.think     = W_Uzi_Flash_Go;\r
844         flash.nextthink = time + 0.02;\r
845         flash.frame     = 2;\r
846         flash.angles_z  = flash.v_angle_z + random() * 180;\r
847         flash.alpha     = 1;\r
848         flash.effects   = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;\r
849 \r
850         self.uzi_bulletcounter = self.uzi_bulletcounter = 0;\r
851     }\r
852 \r
853     self.uzi_bulletcounter = self.uzi_bulletcounter + 1;\r
854     self.tur_head.frame    = self.tur_head.frame + 1;\r
855 }\r
856 \r
857 \r
858 void walker_respawnhook()\r
859 {\r
860     vector vtmp;\r
861     entity e;\r
862 \r
863     self.origin = self.wkr_spawn.origin;\r
864     //self.wkr_props.solid = SOLID_BBOX;\r
865     //self.wkr_props.alpha = 1;\r
866 \r
867     self.angles = self.wkr_spawn.angles;\r
868     vtmp = self.wkr_spawn.origin;\r
869     vtmp_z += self.wkr_spawn.maxs_z;\r
870     setorigin(self,vtmp);\r
871 \r
872     if (self.target != "")\r
873     {\r
874         e = find(world,targetname,self.target);\r
875         if (!e)\r
876         {\r
877             dprint("Warning! initital waypoint for Walker does NOT exsist!\n");\r
878             self.target = "";\r
879         }\r
880 \r
881         if (e.classname != "turret_checkpoint")\r
882             dprint("Warning: not a turrret path\n");\r
883         else\r
884         {\r
885             self.pathcurrent = WALKER_PATH(self.origin,e.origin);\r
886             self.pathgoal = e;\r
887         }\r
888     }\r
889 }\r
890 void walker_diehook()\r
891 {\r
892     turret_trowgib2(self.origin,self.velocity + v_up * 200,'-0.6 -0.2 -02',self,time + random() * 1);\r
893     turret_trowgib2(self.origin + '0 0 64',self.velocity + v_forward * 150 + v_up * 150,'-0.2 -0.2 -02',self.tur_head,time + random() * 2 + 3);\r
894 \r
895     if (self.pathcurrent)\r
896         pathlib_deletepath(self.pathcurrent.owner);\r
897 \r
898     self.pathcurrent = world;\r
899 \r
900     if (self.damage_flags & TFL_DMG_DEATH_NORESPAWN)\r
901     {\r
902         remove(self.wkr_spawn);\r
903 \r
904         verbstack_flush(self.walker_verbs_move);\r
905         verbstack_flush(self.walker_verbs_attack);\r
906         verbstack_flush(self.walker_verbs_idle);\r
907 \r
908         remove(self.walker_verbs_move);\r
909         remove(self.walker_verbs_attack);\r
910         remove(self.walker_verbs_idle);\r
911     }\r
912 \r
913 }\r
914 \r
915 void turret_walker_dinit()\r
916 {\r
917 \r
918     entity e;\r
919 \r
920     if (self.netname == "")      self.netname     = "Walker Turret";\r
921     self.wkr_spawn = spawn();\r
922 \r
923     self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;\r
924     self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_HEADATTACHED;\r
925     self.aim_flags = TFL_AIM_LEAD;\r
926 \r
927     if (cvar("g_antilag_bullets"))\r
928         self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;\r
929     else\r
930         self.aim_flags      |= TFL_AIM_SHOTTIMECOMPENSATE;\r
931 \r
932 \r
933     self.turret_respawnhook = walker_respawnhook;\r
934     self.turret_diehook = walker_diehook;\r
935 \r
936     self.ticrate = 0.05;\r
937     if (turret_stdproc_init("walker_std") == 0)\r
938     {\r
939         remove(self);\r
940         return;\r
941     }\r
942 \r
943     self.walker_verbs_move   = spawn();\r
944     self.walker_verbs_attack = spawn();\r
945     self.walker_verbs_idle   = spawn();\r
946 \r
947     verbstack_push(self.walker_verbs_move, walker_moveverb_idle,   WVM_IDLE,  0);\r
948     verbstack_push(self.walker_verbs_move, walker_moveverb_enemy,  WVM_ENEMY, 0);\r
949     verbstack_push(self.walker_verbs_move, walker_moveverb_path,   WVM_PATH,  0);\r
950 \r
951     verbstack_push(self.walker_verbs_attack, walker_attackverb_meele,   WVA_MEELE,  0);\r
952     verbstack_push(self.walker_verbs_attack, walker_attackverb_rockets, WVA_ROCKET, 0);\r
953 \r
954     self.damage_flags |= TFL_DMG_DEATH_NOGIBS;\r
955 \r
956     //self.target_select_flags   = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;\r
957     //self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;\r
958 \r
959     self.iscreature = TRUE;\r
960     self.movetype   = MOVETYPE_WALK;\r
961     self.solid      = SOLID_SLIDEBOX;\r
962     self.takedamage = DAMAGE_AIM;\r
963 \r
964     setmodel(self,"models/turrets/walker_body.md3");\r
965     setmodel(self.tur_head,"models/turrets/walker_head_minigun.md3");\r
966     setmodel(self.wkr_spawn,"models/turrets/walker_spawn.md3");\r
967 \r
968     setattachment(self.tur_head,self,"tag_head");\r
969 \r
970     self.wkr_spawn.angles   = self.angles;\r
971     self.wkr_spawn.solid    = SOLID_NOT;\r
972 \r
973     traceline(self.origin + '0 0 16', self.origin - '0 0 10000', MOVE_WORLDONLY, self);\r
974     setorigin(self.wkr_spawn,trace_endpos + '0 0 4');\r
975     setorigin(self,self.wkr_spawn.origin);\r
976 \r
977     setsize(self,WALKER_MIN,WALKER_MAX);\r
978 \r
979     self.idle_aim = '0 0 0';\r
980     self.turret_firecheckfunc = walker_firecheck;\r
981     self.turret_firefunc      = walker_attack;\r
982     self.turret_postthink     = walker_postthink;\r
983 \r
984     if (self.target != "")\r
985     {\r
986         e = find(world,targetname,self.target);\r
987         if (!e)\r
988         {\r
989             dprint("Initital waypoint for walker does NOT exsist, fix your map!\n");\r
990             self.target = "";\r
991         }\r
992 \r
993         if (e.classname != "turret_checkpoint")\r
994             dprint("Warning: not a turrret path\n");\r
995         else\r
996         {\r
997             self.pathcurrent = WALKER_PATH(self.origin,e.origin);\r
998             self.pathgoal = e;\r
999         }\r
1000     }\r
1001 }\r
1002 \r
1003 \r
1004 void spawnfunc_turret_walker()\r
1005 {\r
1006     g_turrets_common_precash();\r
1007 \r
1008     precache_model ("models/turrets/walker_head_minigun.md3");\r
1009     precache_model ("models/turrets/walker_body.md3");\r
1010     precache_model ("models/turrets/walker_props.md3");\r
1011     precache_model ("models/turrets/walker_spawn.md3");\r
1012     precache_model ( "models/turrets/rocket.md3");\r
1013     precache_sound ( "weapons/rocket_impact.wav" );\r
1014 \r
1015     self.think = turret_walker_dinit;\r
1016     self.nextthink = time + 0.5;\r
1017 }\r