]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/tturrets/units/unit_ewheel.qc
Fix accuracy stats (#400)
[divverent/nexuiz.git] / data / qcsrc / server / tturrets / units / unit_ewheel.qc
1 void turret_ewheel_projectile_explode()
2 {
3     vector org2;
4
5     org2 = findbetterlocation (self.origin, 8);
6     pointparticles(particleeffectnum("laser_impact"), org2, trace_plane_normal * 1000, 1);
7     //w_deathtypestring = "saw the eweel. to late.";
8 #ifdef TURRET_DEBUG
9     float d;
10
11     d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world, 0);
12     self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
13     self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
14 #else
15     RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world, 0);
16 #endif
17     sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
18
19     remove (self);
20 }
21
22
23 void ewheel_attack()
24 {
25     entity proj;
26     float i;
27
28     for (i=0;i<1;++i)
29     {
30         turret_do_updates(self);
31
32         sound (self, CHAN_WEAPON, "weapons/lasergun_fire.wav", VOL_BASE, ATTN_NORM);
33         pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
34
35         proj                    = spawn ();
36         setorigin(proj, self.tur_shotorg);
37         //setsize(proj, '-0.5 -0.5 -0.5', '0.5 0.5 0.5');
38         //setmodel(proj, "models/laser.mdl"); // precision set above
39         proj.classname       = "ewheel bolt";
40         proj.owner           = self;
41         proj.bot_dodge       = FALSE;
42         proj.bot_dodgerating = self.shot_dmg;
43         proj.think           = turret_ewheel_projectile_explode;
44         proj.nextthink       = time + 9;
45         proj.solid           = SOLID_BBOX;
46         proj.movetype        = MOVETYPE_FLYMISSILE;
47         proj.velocity        = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
48         proj.angles          = vectoangles(proj.velocity);
49         proj.touch           = turret_ewheel_projectile_explode;
50         //proj.effects         = EF_LOWPRECISION |  EF_BRIGHTFIELD;
51         proj.enemy           = self.enemy;
52         proj.flags           = FL_PROJECTILE | FL_NOTARGET;
53
54         CSQCProjectile(proj, TRUE, PROJECTILE_LASER, TRUE);
55
56         self.tur_head.frame += 2;
57
58         if (self.tur_head.frame > 3)
59             self.tur_head.frame = 0;
60     }
61
62 }
63
64 float ewheel_moveverb_roam(float eval)
65 {
66     switch (eval)
67     {
68     case VCM_EVAL:
69
70         if (!self.enemy)
71             return verb.verb_static_value;
72
73         return VS_CALL_NO;
74
75     case VCM_DO:
76         self.angles_z = 0;
77         makevectors(self.angles);
78         self.moveto = v_forward * 128;
79         self.steerto = steerlib_beamsteer(v_forward,1024,32,36,128);
80         self.frame += 1;
81         movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_fast"),0.4);
82
83         return VS_CALL_YES_DOING;
84
85     case VCM_REMOVE:
86
87     }
88
89     return VS_CALL_YES_DONE;
90 }
91
92 float ewheel_moveverb_path(float eval)
93 {
94     switch (eval)
95     {
96     case VCM_EVAL:
97
98         if (self.pathcurrent)
99             return verb.verb_static_value;
100
101         return VS_CALL_NO;
102
103     case VCM_DO:
104         // Do we have a path?
105         if not(self.pathcurrent)
106             return VS_CALL_NO;
107         else
108         {
109             // Are we close enougth to a path node to switch to the next?
110             if (vlen(self.origin  - self.pathcurrent.origin) < 64)
111                 if (self.pathcurrent.path_next == world)
112                 {
113                     // Path endpoint reached
114                     pathlib_deletepath(self.pathcurrent.owner);
115                     self.pathcurrent = world;
116
117                     if (self.pathgoal)
118                     {
119                         if (self.pathgoal.use)
120                             self.pathgoal.use();
121
122                         if (self.pathgoal.enemy)
123                         {
124                             self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin);
125                             self.pathgoal = self.pathgoal.enemy;
126                         }
127                     }
128                     else
129                         self.pathgoal = world;
130                 }
131                 else
132                     self.pathcurrent = self.pathcurrent.path_next;
133         }
134
135
136         if (self.pathcurrent)
137         {
138             switch (self.waterlevel)
139             {
140             case 0:
141             case 1:
142             case 2:
143             case 3:
144             }
145
146             self.moveto = self.pathcurrent.origin;
147             self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
148
149             self.frame += 1;
150             movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_fast"),0.4);
151
152             return VS_CALL_YES_DOING;
153         }
154         else
155             return VS_CALL_YES_DONE;
156
157     case VCM_REMOVE:
158
159         if (self.pathcurrent)
160             pathlib_deletepath(self.pathcurrent.owner);
161
162         self.pathcurrent = world;
163
164         return VS_CALL_YES_DONE;
165     }
166
167     return VS_CALL_YES_DONE;
168 }
169
170 float ewheel_moveverb_enemy(float eval)
171 {
172     switch (eval)
173     {
174     case VCM_EVAL:
175         if (self.enemy)
176         {
177             if (self.spawnflags & TSF_NO_PATHBREAK)
178                 if (self.pathcurrent)
179                     return VS_CALL_NO;
180
181             return verb.verb_static_value;
182         }
183
184         return VS_CALL_NO;
185
186     case VCM_DO:
187
188         self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
189         self.steerto = steerlib_beamsteer(self.steerto,1024,64,68,256);
190         self.moveto  = self.origin + self.steerto * 128;
191
192         makevectors(self.angles);
193
194         if (self.tur_dist_enemy > self.target_range_optimal)
195         {
196             if ( self.tur_head.spawnshieldtime < 1 )
197             {
198                 self.frame += 2;
199                 movelib_move_simple(v_forward ,cvar("g_turrets_unit_ewheel_speed_fast"),0.4);
200             }
201             else if (self.tur_head.spawnshieldtime < 2)
202             {
203
204                 self.frame += 1;
205                 movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_slow"),0.4);
206            }
207             else
208             {
209                 self.frame += 1;
210                 movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_slower"),0.4);
211             }
212         }
213         else if (self.tur_dist_enemy < self.target_range_min)
214         {
215             self.frame -= 1;
216             movelib_move_simple(v_forward * -1,cvar("g_turrets_unit_ewheel_speed_slow"),0.4);
217         }
218         else
219         {
220             movelib_beak_simple(cvar("g_turrets_unit_ewheel_speed_stop"));
221         }
222
223         return VS_CALL_YES_DOING;
224     }
225
226
227     return VS_CALL_YES_DONE;
228 }
229
230 float ewheel_moveverb_runaway(float eval)
231 {
232     switch (eval)
233     {
234     case VCM_EVAL:
235         if (self.spawnflags & TSF_NO_PATHBREAK)
236             if (self.pathcurrent)
237                 return VS_CALL_NO;
238
239         if (self.enemy)
240             if (self.health < 50)
241                 return verb.verb_static_value;
242
243         return VS_CALL_NO;
244
245     case VCM_DO:
246         self.steerto = (steerlib_push(self.enemy.origin) * 0.7) + (steerlib_traceavoid_flat(0.3, 500, '0 0 128') * 0.3);
247         self.moveto  = self.origin + self.steerto * 1000;
248
249         self.frame += 2;
250         movelib_move_simple(v_forward ,cvar("g_turrets_unit_ewheel_speed_fast"),0.4);
251
252         return VS_CALL_YES_DOING;
253
254     }
255
256     return VS_CALL_YES_DONE;
257 }
258
259 float ewheel_moveverb_idle(float eval)
260 {
261     switch (eval)
262     {
263     case VCM_EVAL:
264         if (self.enemy)
265             return VS_CALL_NO;
266
267         return verb.verb_static_value;
268
269     case VCM_DO:
270         self.moveto = self.origin;
271
272         if (vlen(self.velocity))
273             movelib_beak_simple(cvar("g_turrets_unit_ewheel_speed_stop"));
274
275         return VS_CALL_YES_DOING;
276     }
277
278     return VS_CALL_YES_DONE;
279 }
280
281 void ewheel_postthink()
282 {
283     float vz;
284     vector wish_angle,real_angle;
285
286     vz = self.velocity_z;
287
288     self.angles_x = anglemods(self.angles_x);
289     self.angles_y = anglemods(self.angles_y);
290
291     self.angles_x *= -1;
292     makevectors(self.angles);
293     self.angles_x *= -1;
294
295     wish_angle = normalize(self.steerto);
296     wish_angle = vectoangles(wish_angle);
297     real_angle = wish_angle - self.angles;
298     real_angle = shortangle_vxy(real_angle,self.tur_head.angles);
299
300     self.tur_head.spawnshieldtime = fabs(real_angle_y);
301     real_angle_y  = bound(-self.tur_head.aim_speed,real_angle_y,self.tur_head.aim_speed);
302     self.angles_y = (self.angles_y + real_angle_y);
303
304     // Simulate banking
305     self.angles_z = bound(-45,real_angle_y * -2.5,45);
306
307     verbstack_pop(self.verbs_move);
308
309     if (self.frame > 40)
310         self.frame = 1;
311
312     if (self.frame < 1)
313         self.frame = 40;
314
315
316     self.velocity_z = vz;
317 }
318
319 void ewheel_respawnhook()
320 {
321     entity e;
322
323     setorigin(self,self.pos1);
324
325     if (self.target != "")
326     {
327         e = find(world,targetname,self.target);
328         if (!e)
329         {
330             dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
331             self.target = "";
332         }
333
334         if (e.classname != "turret_checkpoint")
335             dprint("Warning: not a turrret path\n");
336         else
337         {
338             self.pathcurrent = WALKER_PATH(self.origin,e.origin);
339             self.pathgoal = e;
340         }
341     }
342 }
343
344 void ewheel_diehook()
345 {
346     turret_trowgib2(self.origin,self.velocity + v_up * 400,'-0.6 -0.2 -02',self,time + random() * 2 +3);
347
348     if (self.pathcurrent)
349         pathlib_deletepath(self.pathcurrent.owner);
350
351     self.pathcurrent = world;
352
353     if (self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
354     {
355         verbstack_flush(self.verbs_move);
356         remove(self.verbs_move);
357     }
358
359 }
360
361 /*
362 float test_stack_1(float eval)
363 {
364     switch (eval)
365     {
366     case VCM_EVAL:
367         return verb.verb_static_value;
368
369     case VCM_DO:
370         dprint("test_stack_1\n");
371         return VS_CALL_REMOVE;
372     }
373
374     return VS_CALL_REMOVE;
375 }
376
377 float test_stack_2(float eval)
378 {
379     switch (eval)
380     {
381     case VCM_EVAL:
382         return verb.verb_static_value;
383
384     case VCM_DO:
385         dprint("test_stack_2\n");
386         return VS_CALL_REMOVE;
387     }
388
389     return VS_CALL_REMOVE;
390 }
391
392 float ccnntt;
393 float test_stack_3(float eval)
394 {
395     switch (eval)
396     {
397     case VCM_EVAL:
398         return verb.verb_static_value;
399
400     case VCM_DO:
401         dprint("test_stack_3\n");
402         ++ccnntt;
403         if(ccnntt > 3)
404             return VS_CALL_REMOVE;
405         else
406             return VS_CALL_YES_DONE;
407     }
408
409     return VS_CALL_YES_DONE;
410 }
411
412 .entity test_stack;
413 */
414 void turret_ewheel_dinit()
415 {
416     entity e;
417
418     if (self.netname == "")      self.netname     = "eWheel Turret";
419
420     if (self.target != "")
421     {
422         e = find(world,targetname,self.target);
423         if (!e)
424         {
425             bprint("Warning! initital waypoint for ewheel does NOT exsist!\n");
426             self.target = "";
427         }
428
429         if (e.classname != "turret_checkpoint")
430             dprint("Warning: not a turrret path\n");
431         else
432             self.goalcurrent = e;
433     }
434
435     self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
436     self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_ROAM | TFL_TURRCAPS_HEADATTACHED;
437     //self.aim_flags = TFL_AIM_SIMPLE;// TFL_AIM_LEAD | TFL_AIM_ZEASE;
438
439     self.turret_respawnhook = ewheel_respawnhook;
440     self.turret_diehook = ewheel_diehook;
441
442     if (turret_stdproc_init("ewheel_std",0) == 0)
443     {
444         remove(self);
445         return;
446     }
447
448     self.target_select_flags   = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
449     self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;// | TFL_TARGETSELECT_LOS;
450     self.damage_flags          |= TFL_DMG_DEATH_NOGIBS;
451
452     self.iscreature = TRUE;
453     self.movetype   = MOVETYPE_WALK;
454     self.solid      = SOLID_SLIDEBOX;
455     self.takedamage = DAMAGE_AIM;
456
457     setmodel(self,"models/turrets/ewheel-base.md3");
458     setmodel(self.tur_head,"models/turrets/ewheel-gun1.md3");
459     setattachment(self.tur_head,self,"tag_head");
460
461     self.pos1 = self.origin;
462
463     self.idle_aim = '0 0 0';
464
465     // Our fire routine
466     self.turret_firefunc  = ewheel_attack;
467     self.turret_postthink = ewheel_postthink;
468     self.tur_head.frame = 1;
469
470     self.verbs_move = spawn();
471
472     //verbstack_push(self.verbs_move, ewheel_moveverb_roam,   WVM_IDLE,  0, self);
473     verbstack_push(self.verbs_move, ewheel_moveverb_idle,   WVM_IDLE,  0, self);
474     verbstack_push(self.verbs_move, ewheel_moveverb_enemy,  WVM_ENEMY, 0, self);
475     verbstack_push(self.verbs_move, ewheel_moveverb_path,   WVM_PATH,  0, self);
476     //verbstack_push(self.verbs_move, ewheel_moveverb_runaway,WVM_PANIC,  0, self);
477
478     /*
479     self.test_stack = spawn();
480     verbstack_push(self.test_stack, test_stack_1,1,  0, self);
481     verbstack_push(self.test_stack, test_stack_2,2,  0, self);
482     verbstack_push(self.test_stack, test_stack_3,100,0, self);
483     while(verbstack_popfifo(self.test_stack) != 0)
484     */
485
486
487
488     // Convert from dgr / sec to dgr / tic
489     self.tur_head.aim_speed = cvar("g_turrets_unit_ewheel_turnrate");
490     self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate);
491
492     if (self.target != "")
493     {
494         e = find(world,targetname,self.target);
495         if (!e)
496         {
497             dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
498             self.target = "";
499         }
500
501         if (e.classname != "turret_checkpoint")
502             dprint("Warning: not a turrret path\n");
503         else
504         {
505             self.pathcurrent = WALKER_PATH(self.origin,e.origin);
506             self.pathgoal = e;
507         }
508     }
509 }
510
511 void spawnfunc_turret_ewheel()
512 {
513     g_turrets_common_precash();
514
515     precache_model ("models/turrets/ewheel-base.md3");
516     precache_model ("models/turrets/ewheel-gun1.md3");
517
518     self.think = turret_ewheel_dinit;
519     self.nextthink = time + 0.5;
520 }