]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/turrets/turret/walker.qc
Turrets: delete 401 lines
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / turrets / turret / walker.qc
1 #ifndef TUR_WALKER_H
2 #define TUR_WALKER_H
3
4 CLASS(WalkerTurretAttack, PortoLaunch)
5 /* flags     */ ATTRIB(WalkerTurretAttack, spawnflags, int, WEP_TYPE_OTHER);
6 /* impulse   */ ATTRIB(WalkerTurretAttack, impulse, int, 5);
7 /* refname   */ ATTRIB(WalkerTurretAttack, netname, string, "turret_walker");
8 /* wepname   */ ATTRIB(WalkerTurretAttack, message, string, _("Walker"));
9 ENDCLASS(WalkerTurretAttack)
10 REGISTER_WEAPON(WALKER, NEW(WalkerTurretAttack));
11
12 //#define WALKER_FANCYPATHING
13
14 CLASS(WalkerTurret, Turret)
15 /* spawnflags */ ATTRIB(WalkerTurret, spawnflags, int, TUR_FLAG_PLAYER | TUR_FLAG_MOVE);
16 /* mins       */ ATTRIB(WalkerTurret, mins, vector, '-70 -70 0');
17 /* maxs       */ ATTRIB(WalkerTurret, maxs, vector, '70 70 95');
18 /* modelname  */ ATTRIB(WalkerTurret, mdl, string, "walker_body.md3");
19 /* model      */ ATTRIB(WalkerTurret, model, string, strzone(strcat("models/turrets/", this.mdl)));
20 /* head_model */ ATTRIB(WalkerTurret, head_model, string, strzone(strcat("models/turrets/", "walker_head_minigun.md3")));
21 /* netname    */ ATTRIB(WalkerTurret, netname, string, "walker");
22 /* fullname   */ ATTRIB(WalkerTurret, turret_name, string, _("Walker Turret"));
23     ATTRIB(WalkerTurret, m_weapon, Weapon, WEP_WALKER);
24 ENDCLASS(WalkerTurret)
25 REGISTER_TURRET(WALKER, NEW(WalkerTurret));
26
27 #endif
28
29 #ifdef IMPLEMENTATION
30 #ifdef SVQC
31 METHOD(WalkerTurretAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
32     SELFPARAM();
33     bool isPlayer = IS_PLAYER(self);
34     if (fire1)
35     if (!isPlayer || weapon_prepareattack(false, WEP_CVAR_PRI(electro, refire))) {
36         if (isPlayer) {
37             turret_initparams(self);
38             W_SetupShot_Dir(self, v_forward, false, 0, W_Sound("electro_fire"), CH_WEAPON_B, 0);
39             self.tur_shotdir_updated = w_shotdir;
40             self.tur_shotorg = w_shotorg;
41             self.tur_head = self;
42             weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
43         }
44         sound (self, CH_WEAPON_A, SND_UZI_FIRE, VOL_BASE, ATTEN_NORM);
45         fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_WALK_GUN, 0);
46         Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
47     }
48     return true;
49 }
50
51 float autocvar_g_turrets_unit_walker_melee_damage;
52 float autocvar_g_turrets_unit_walker_melee_force;
53 float autocvar_g_turrets_unit_walker_melee_range;
54 float autocvar_g_turrets_unit_walker_rocket_damage;
55 float autocvar_g_turrets_unit_walker_rocket_radius;
56 float autocvar_g_turrets_unit_walker_rocket_force;
57 float autocvar_g_turrets_unit_walker_rocket_speed;
58 float autocvar_g_turrets_unit_walker_rocket_range;
59 float autocvar_g_turrets_unit_walker_rocket_range_min;
60 float autocvar_g_turrets_unit_walker_rocket_refire;
61 float autocvar_g_turrets_unit_walker_rocket_turnrate;
62 float autocvar_g_turrets_unit_walker_speed_stop;
63 float autocvar_g_turrets_unit_walker_speed_walk;
64 float autocvar_g_turrets_unit_walker_speed_run;
65 float autocvar_g_turrets_unit_walker_speed_jump;
66 float autocvar_g_turrets_unit_walker_speed_swim;
67 float autocvar_g_turrets_unit_walker_speed_roam;
68 float autocvar_g_turrets_unit_walker_turn;
69 float autocvar_g_turrets_unit_walker_turn_walk;
70 float autocvar_g_turrets_unit_walker_turn_strafe;
71 float autocvar_g_turrets_unit_walker_turn_swim;
72 float autocvar_g_turrets_unit_walker_turn_run;
73
74 const int ANIM_NO         = 0;
75 const int ANIM_TURN       = 1;
76 const int ANIM_WALK       = 2;
77 const int ANIM_RUN        = 3;
78 const int ANIM_STRAFE_L   = 4;
79 const int ANIM_STRAFE_R   = 5;
80 const int ANIM_JUMP       = 6;
81 const int ANIM_LAND       = 7;
82 const int ANIM_PAIN       = 8;
83 const int ANIM_MELEE      = 9;
84 const int ANIM_SWIM       = 10;
85 const int ANIM_ROAM       = 11;
86
87 .float animflag;
88 .float idletime;
89
90 #define WALKER_PATH(s,e) pathlib_astar(s,e)
91
92 float walker_firecheck()
93 {SELFPARAM();
94     if (self.animflag == ANIM_MELEE)
95         return 0;
96
97     return turret_firecheck();
98 }
99
100 void walker_melee_do_dmg()
101 {SELFPARAM();
102     vector where;
103     entity e;
104
105     makevectors(self.angles);
106     where = self.origin + v_forward * 128;
107
108     e = findradius(where,32);
109     while (e)
110     {
111         if (turret_validate_target(self, e, self.target_validate_flags))
112             if (e != self && e.owner != self)
113                 Damage(e, self, self, (autocvar_g_turrets_unit_walker_melee_damage), DEATH_TURRET_WALK_MELEE, '0 0 0', v_forward * (autocvar_g_turrets_unit_walker_melee_force));
114
115         e = e.chain;
116     }
117 }
118
119 void walker_setnoanim()
120 {SELFPARAM();
121     turrets_setframe(ANIM_NO, false);
122     self.animflag = self.frame;
123 }
124 void walker_rocket_explode()
125 {SELFPARAM();
126     RadiusDamage (self, self.owner, (autocvar_g_turrets_unit_walker_rocket_damage), 0, (autocvar_g_turrets_unit_walker_rocket_radius), self, world, (autocvar_g_turrets_unit_walker_rocket_force), DEATH_TURRET_WALK_ROCKET, world);
127     remove (self);
128 }
129
130 void walker_rocket_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
131 {SELFPARAM();
132     self.health = self.health - damage;
133     self.velocity = self.velocity + vforce;
134
135     if (self.health <= 0)
136         W_PrepareExplosionByDamage(self.owner, walker_rocket_explode);
137 }
138
139 #define WALKER_ROCKET_MOVE movelib_move_simple(newdir, (autocvar_g_turrets_unit_walker_rocket_speed), (autocvar_g_turrets_unit_walker_rocket_turnrate)); UpdateCSQCProjectile(self)
140 void walker_rocket_loop();
141 void walker_rocket_think()
142 {SELFPARAM();
143     vector newdir;
144     float edist;
145     float itime;
146     float m_speed;
147
148     self.nextthink = time;
149
150     edist = vlen(self.enemy.origin - self.origin);
151
152     // Simulate crude guidance
153     if (self.cnt < time)
154     {
155         if (edist < 1000)
156             self.tur_shotorg = randomvec() * min(edist, 64);
157         else
158             self.tur_shotorg = randomvec() * min(edist, 256);
159
160         self.cnt = time + 0.5;
161     }
162
163     if (edist < 128)
164         self.tur_shotorg = '0 0 0';
165
166     if (self.max_health < time)
167     {
168         self.think        = walker_rocket_explode;
169         self.nextthink  = time;
170         return;
171     }
172
173     if (self.shot_dmg != 1337 && random() < 0.01)
174     {
175         walker_rocket_loop();
176         return;
177     }
178
179     m_speed = vlen(self.velocity);
180
181     // Enemy dead? just keep on the current heading then.
182     if (self.enemy == world || self.enemy.deadflag != DEAD_NO)
183         self.enemy = world;
184
185     if (self.enemy)
186     {
187         itime = max(edist / m_speed, 1);
188         newdir = steerlib_pull(self.enemy.origin + self.tur_shotorg);
189     }
190     else
191         newdir  = normalize(self.velocity);
192
193     WALKER_ROCKET_MOVE;
194 }
195
196 void walker_rocket_loop3()
197 {SELFPARAM();
198     vector newdir;
199     self.nextthink = time;
200
201     if (self.max_health < time)
202     {
203         self.think = walker_rocket_explode;
204         return;
205     }
206
207     if (vlen(self.origin - self.tur_shotorg) < 100 )
208     {
209         self.think = walker_rocket_think;
210         return;
211     }
212
213     newdir = steerlib_pull(self.tur_shotorg);
214     WALKER_ROCKET_MOVE;
215
216     self.angles = vectoangles(self.velocity);
217 }
218
219 void walker_rocket_loop2()
220 {SELFPARAM();
221     vector newdir;
222
223     self.nextthink = time;
224
225     if (self.max_health < time)
226     {
227         self.think = walker_rocket_explode;
228         return;
229     }
230
231     if (vlen(self.origin - self.tur_shotorg) < 100 )
232     {
233         self.tur_shotorg = self.origin - '0 0 200';
234         self.think = walker_rocket_loop3;
235         return;
236     }
237
238     newdir = steerlib_pull(self.tur_shotorg);
239     WALKER_ROCKET_MOVE;
240 }
241
242 void walker_rocket_loop()
243 {SELFPARAM();
244     self.nextthink = time;
245     self.tur_shotorg = self.origin + '0 0 300';
246     self.think = walker_rocket_loop2;
247     self.shot_dmg = 1337;
248 }
249
250 void walker_fire_rocket(vector org)
251 {SELFPARAM();
252     entity rocket;
253
254     fixedmakevectors(self.angles);
255
256     te_explosion (org);
257
258     rocket = spawn ();
259     setorigin(rocket, org);
260
261     sound (self, CH_WEAPON_A, SND_HAGAR_FIRE, VOL_BASE, ATTEN_NORM);
262     setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
263
264     rocket.classname              = "walker_rocket";
265     rocket.owner                          = self;
266     rocket.bot_dodge              = true;
267     rocket.bot_dodgerating      = 50;
268     rocket.takedamage            = DAMAGE_YES;
269     rocket.damageforcescale   = 2;
270     rocket.health                        = 25;
271     rocket.tur_shotorg          = randomvec() * 512;
272     rocket.cnt                          = time + 1;
273     rocket.enemy                          = self.enemy;
274
275     if (random() < 0.01)
276         rocket.think              = walker_rocket_loop;
277     else
278         rocket.think              = walker_rocket_think;
279
280     rocket.event_damage    = walker_rocket_damage;
281
282     rocket.nextthink              = time;
283     rocket.movetype                = MOVETYPE_FLY;
284     rocket.velocity                = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * (autocvar_g_turrets_unit_walker_rocket_speed);
285     rocket.angles                        = vectoangles(rocket.velocity);
286     rocket.touch                          = walker_rocket_explode;
287     rocket.flags                          = FL_PROJECTILE;
288     rocket.solid                          = SOLID_BBOX;
289     rocket.max_health            = time + 9;
290     rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
291
292     CSQCProjectile(rocket, false, PROJECTILE_ROCKET, false); // no culling, has fly sound
293 }
294
295 .vector enemy_last_loc;
296 .float enemy_last_time;
297 void walker_move_to(vector _target, float _dist)
298 {SELFPARAM();
299     switch (self.waterlevel)
300     {
301         case WATERLEVEL_NONE:
302             if (_dist > 500)
303                 self.animflag = ANIM_RUN;
304             else
305                 self.animflag = ANIM_WALK;
306         case WATERLEVEL_WETFEET:
307         case WATERLEVEL_SWIMMING:
308             if (self.animflag != ANIM_SWIM)
309                 self.animflag = ANIM_WALK;
310             else
311                 self.animflag = ANIM_SWIM;
312             break;
313         case WATERLEVEL_SUBMERGED:
314             self.animflag = ANIM_SWIM;
315     }
316
317     self.moveto = _target;
318     self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
319
320     if(self.enemy)
321     {
322         self.enemy_last_loc = _target;
323         self.enemy_last_time = time;
324     }
325 }
326
327 void walker_move_path()
328 {SELFPARAM();
329 #ifdef WALKER_FANCYPATHING
330     // Are we close enougth to a path node to switch to the next?
331     if (vlen(self.origin  - self.pathcurrent.origin) < 64)
332         if (self.pathcurrent.path_next == world)
333         {
334             // Path endpoint reached
335             pathlib_deletepath(self.pathcurrent.owner);
336             self.pathcurrent = world;
337
338             if (self.pathgoal)
339             {
340                 if (self.pathgoal.use)
341                     self.pathgoal.use();
342
343                 if (self.pathgoal.enemy)
344                 {
345                     self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin);
346                     self.pathgoal = self.pathgoal.enemy;
347                 }
348             }
349             else
350                 self.pathgoal = world;
351         }
352         else
353             self.pathcurrent = self.pathcurrent.path_next;
354
355     self.moveto = self.pathcurrent.origin;
356     self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
357     walker_move_to(self.moveto, 0);
358
359 #else
360     if (vlen(self.origin - self.pathcurrent.origin) < 64)
361         self.pathcurrent = self.pathcurrent.enemy;
362
363     if(!self.pathcurrent)
364         return;
365
366     self.moveto = self.pathcurrent.origin;
367     self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
368     walker_move_to(self.moveto, 0);
369 #endif
370 }
371
372 void spawnfunc_turret_walker() { SELFPARAM(); if(!turret_initialize(TUR_WALKER)) remove(self); }
373
374         METHOD(WalkerTurret, tr_think, void(WalkerTurret thistur))
375         {
376             fixedmakevectors(self.angles);
377
378             if (self.spawnflags & TSF_NO_PATHBREAK && self.pathcurrent)
379                 walker_move_path();
380             else if (self.enemy == world)
381             {
382                 if(self.pathcurrent)
383                     walker_move_path();
384                 else
385                 {
386                     if(self.enemy_last_time != 0)
387                     {
388                         if(vlen(self.origin - self.enemy_last_loc) < 128 || time - self.enemy_last_time > 10)
389                             self.enemy_last_time = 0;
390                         else
391                             walker_move_to(self.enemy_last_loc, 0);
392                     }
393                     else
394                     {
395                         if(self.animflag != ANIM_NO)
396                         {
397                             traceline(self.origin + '0 0 64', self.origin + '0 0 64' + v_forward * 128, MOVE_NORMAL, self);
398
399                             if(trace_fraction != 1.0)
400                                 self.tur_head.idletime = -1337;
401                             else
402                             {
403                                 traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self);
404                                 if(trace_fraction == 1.0)
405                                     self.tur_head.idletime = -1337;
406                             }
407
408                             if(self.tur_head.idletime == -1337)
409                             {
410                                 self.moveto = self.origin + randomvec() * 256;
411                                 self.tur_head.idletime = 0;
412                             }
413
414                             self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1;
415                             self.moveto_z = self.origin_z + 64;
416                             walker_move_to(self.moveto, 0);
417                         }
418
419                         if(self.idletime < time)
420                         {
421                             if(random() < 0.5 || !(self.spawnflags & TSL_ROAM))
422                             {
423                                 self.idletime = time + 1 + random() * 5;
424                                 self.moveto = self.origin;
425                                 self.animflag = ANIM_NO;
426                             }
427                             else
428                             {
429                                 self.animflag = ANIM_WALK;
430                                 self.idletime = time + 4 + random() * 2;
431                                 self.moveto = self.origin + randomvec() * 256;
432                                 self.tur_head.moveto = self.moveto;
433                                 self.tur_head.idletime = 0;
434                             }
435                         }
436                     }
437                 }
438             }
439             else
440             {
441                 if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_melee_range) && self.animflag != ANIM_MELEE)
442                 {
443                     vector wish_angle;
444
445                     wish_angle = angleofs(self, self.enemy);
446                     if (self.animflag != ANIM_SWIM)
447                     if (fabs(wish_angle_y) < 15)
448                     {
449                         self.moveto   = self.enemy.origin;
450                         self.steerto  = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
451                         self.animflag = ANIM_MELEE;
452                     }
453                 }
454                 else if (self.tur_head.attack_finished_single < time)
455                 {
456                     if(self.tur_head.shot_volly)
457                     {
458                         self.animflag = ANIM_NO;
459
460                         self.tur_head.shot_volly = self.tur_head.shot_volly -1;
461                         if(self.tur_head.shot_volly == 0)
462                             self.tur_head.attack_finished_single = time + (autocvar_g_turrets_unit_walker_rocket_refire);
463                         else
464                             self.tur_head.attack_finished_single = time + 0.2;
465
466                         if(self.tur_head.shot_volly > 1)
467                             walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01")));
468                         else
469                             walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket02")));
470                     }
471                     else
472                     {
473                         if (self.tur_dist_enemy > (autocvar_g_turrets_unit_walker_rocket_range_min))
474                         if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_rocket_range))
475                             self.tur_head.shot_volly = 4;
476                     }
477                 }
478                 else
479                 {
480                     if (self.animflag != ANIM_MELEE)
481                         walker_move_to(self.enemy.origin, self.tur_dist_enemy);
482                 }
483             }
484
485             {
486                 vector real_angle;
487                 float turny = 0, turnx = 0;
488                 float vz;
489
490                 real_angle = vectoangles(self.steerto) - self.angles;
491                 vz = self.velocity_z;
492
493                 switch (self.animflag)
494                 {
495                     case ANIM_NO:
496                         movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
497                         break;
498
499                     case ANIM_TURN:
500                         turny = (autocvar_g_turrets_unit_walker_turn);
501                         movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
502                         break;
503
504                     case ANIM_WALK:
505                         turny = (autocvar_g_turrets_unit_walker_turn_walk);
506                         movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_walk), 0.6);
507                         break;
508
509                     case ANIM_RUN:
510                         turny = (autocvar_g_turrets_unit_walker_turn_run);
511                         movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_run), 0.6);
512                         break;
513
514                     case ANIM_STRAFE_L:
515                         turny = (autocvar_g_turrets_unit_walker_turn_strafe);
516                         movelib_move_simple(v_right * -1, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
517                         break;
518
519                     case ANIM_STRAFE_R:
520                         turny = (autocvar_g_turrets_unit_walker_turn_strafe);
521                         movelib_move_simple(v_right, (autocvar_g_turrets_unit_walker_speed_walk), 0.8);
522                         break;
523
524                     case ANIM_JUMP:
525                         self.velocity += '0 0 1' * (autocvar_g_turrets_unit_walker_speed_jump);
526                         break;
527
528                     case ANIM_LAND:
529                         break;
530
531                     case ANIM_PAIN:
532                         if(self.frame != ANIM_PAIN)
533                             defer(0.25, walker_setnoanim);
534
535                         break;
536
537                     case ANIM_MELEE:
538                         if(self.frame != ANIM_MELEE)
539                         {
540                             defer(0.41, walker_setnoanim);
541                             defer(0.21, walker_melee_do_dmg);
542                         }
543
544                         movelib_beak_simple((autocvar_g_turrets_unit_walker_speed_stop));
545                         break;
546
547                     case ANIM_SWIM:
548                         turny = (autocvar_g_turrets_unit_walker_turn_swim);
549                         turnx = (autocvar_g_turrets_unit_walker_turn_swim);
550
551                         self.angles_x += bound(-10, shortangle_f(real_angle_x, self.angles_x), 10);
552                         movelib_move_simple(v_forward, (autocvar_g_turrets_unit_walker_speed_swim), 0.3);
553                         vz = self.velocity_z + sin(time * 4) * 8;
554                         break;
555
556                     case ANIM_ROAM:
557                         turny = (autocvar_g_turrets_unit_walker_turn_walk);
558                         movelib_move_simple(v_forward ,(autocvar_g_turrets_unit_walker_speed_roam), 0.5);
559                         break;
560                 }
561
562                 if(turny)
563                 {
564                     turny = bound( turny * -1, shortangle_f(real_angle_y, self.angles_y), turny );
565                     self.angles_y += turny;
566                 }
567
568                 if(turnx)
569                 {
570                     turnx = bound( turnx * -1, shortangle_f(real_angle_x, self.angles_x), turnx );
571                     self.angles_x += turnx;
572                 }
573
574                 self.velocity_z = vz;
575             }
576
577
578             if(self.origin != self.oldorigin)
579                 self.SendFlags |= TNSF_MOVE;
580
581             self.oldorigin = self.origin;
582             turrets_setframe(self.animflag, false);
583         }
584         METHOD(WalkerTurret, tr_death, void(WalkerTurret this, entity it))
585         {
586 #ifdef WALKER_FANCYPATHING
587             if (it.pathcurrent)
588                 pathlib_deletepath(it.pathcurrent.owner);
589 #endif
590             it.pathcurrent = NULL;
591         }
592         METHOD(WalkerTurret, tr_setup, void(WalkerTurret this, entity it))
593         {
594             it.ticrate = 0.05;
595
596             entity e;
597
598             // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn.
599             if(it.movetype == MOVETYPE_WALK)
600             {
601                 if(it.pos1)
602                     setorigin(it, it.pos1);
603                 if(it.pos2)
604                     it.angles = it.pos2;
605             }
606
607             it.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
608             it.aim_flags = TFL_AIM_LEAD;
609             it.turret_flags |= TUR_FLAG_HITSCAN;
610
611             it.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
612             it.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
613             it.iscreature = true;
614             it.teleportable = TELEPORT_NORMAL;
615             it.damagedbycontents = true;
616             it.solid = SOLID_SLIDEBOX;
617             it.takedamage = DAMAGE_AIM;
618             if(it.movetype != MOVETYPE_WALK)
619             {
620                 setorigin(it, it.origin);
621                 tracebox(it.origin + '0 0 128', it.mins, it.maxs, it.origin - '0 0 10000', MOVE_NORMAL, it);
622                 setorigin(it, trace_endpos + '0 0 4');
623                 it.pos1 = it.origin;
624                 it.pos2 = it.angles;
625             }
626             it.movetype = MOVETYPE_WALK;
627             it.idle_aim = '0 0 0';
628             it.turret_firecheckfunc = walker_firecheck;
629
630             if (it.target != "")
631             {
632                 e = find(world, targetname, it.target);
633                 if (!e)
634                 {
635                     LOG_TRACE("Initital waypoint for walker does NOT exsist, fix your map!\n");
636                     it.target = "";
637                 }
638
639                 if (e.classname != "turret_checkpoint")
640                     LOG_TRACE("Warning: not a turrret path\n");
641                 else
642                 {
643 #ifdef WALKER_FANCYPATHING
644                     it.pathcurrent = WALKER_PATH(it.origin, e.origin);
645                     it.pathgoal = e;
646 #else
647                     it.pathcurrent = e;
648 #endif
649                 }
650             }
651         }
652
653 #endif // SVQC
654 #ifdef CSQC
655
656 #include "../../../client/movelib.qh"
657
658 void walker_draw()
659 {SELFPARAM();
660     float dt;
661
662     dt = time - self.move_time;
663     self.move_time = time;
664     if(dt <= 0)
665         return;
666
667     fixedmakevectors(self.angles);
668     movelib_groundalign4point(300, 100, 0.25, 45);
669     setorigin(self, self.origin + self.velocity * dt);
670     self.tur_head.angles += dt * self.tur_head.move_avelocity;
671     self.angles_y = self.move_angles_y;
672
673     if (self.health < 127)
674     if(random() < 0.15)
675         te_spark(self.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
676 }
677
678         METHOD(WalkerTurret, tr_setup, void(WalkerTurret this, entity it))
679         {
680             it.gravity          = 1;
681             it.movetype         = MOVETYPE_BOUNCE;
682             it.move_movetype    = MOVETYPE_BOUNCE;
683             it.move_origin      = it.origin;
684             it.move_time                = time;
685             it.draw                     = walker_draw;
686         }
687
688 #endif // CSQC
689 #endif