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