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