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