]> icculus.org git repositories - divverent/nexuiz.git/blob - attic/TeamNexuiz/game/gamec/tfsentry.c
now menu qc respects g_campaign_name
[divverent/nexuiz.git] / attic / TeamNexuiz / game / gamec / tfsentry.c
1 void (entity bld) CheckBelowBuilding;\r
2 void (entity gunhead) CheckSentry;\r
3 void () Sentry_Rotate;\r
4 float () Sentry_FindTarget;\r
5 void () Sentry_FoundTarget;\r
6 void () Sentry_HuntTarget;\r
7 void () Sentry_Pain;\r
8 void () Sentry_Die;\r
9 float () Sentry_Fire;\r
10 void () Sentry_MuzzleFlash;\r
11 void () lvl1_sentry_atk3;\r
12 \r
13 float(entity targ) tfvisible = \r
14 {\r
15         local vector spot1;\r
16         local vector spot2;\r
17         spot1 = self.origin + '0 0 20' + self.view_ofs + '0 0 20';\r
18         spot2 = targ.origin + targ.view_ofs;\r
19         traceline(spot1, spot2, TF_FLARE_OFF, self);\r
20         if (trace_inopen && trace_inwater)\r
21         {\r
22                 return TF_FLARE_LIT;\r
23         }\r
24         if (trace_fraction == TF_FLARE_OFF)\r
25         {\r
26                 return TF_FLARE_OFF;\r
27         }\r
28         return TF_FLARE_LIT;\r
29 };\r
30 \r
31 \r
32 void () lvl1_sentry_stand = [ 0, lvl1_sentry_stand ]\r
33 {\r
34         Sentry_Rotate ();\r
35 };\r
36 \r
37 void () lvl1_sentry_atk1 = [ 1, lvl1_sentry_atk3 ]\r
38 {\r
39         ai_face ();\r
40 \r
41         local vector temp;\r
42         temp = vectoangles(self.enemy.origin - self.origin);\r
43         self.barrel_ent.angles_x = -temp_x;\r
44 \r
45         if (((((self.enemy == world) || (self.enemy.health <= 0)) || !tfvisible (self.enemy)) || (self.enemy.has_disconnected == 1)))\r
46         {\r
47                 lvl1_sentry_stand ();\r
48         }\r
49         else\r
50         {\r
51                 if ((self.ammo_shells <= 0))\r
52                 {\r
53                         lvl1_sentry_stand ();\r
54                 }\r
55                 else\r
56                 {\r
57                         if ((Sentry_Fire () == 0))\r
58                         {\r
59                                 lvl1_sentry_atk3 ();\r
60                         }\r
61                 }\r
62         }\r
63 };\r
64 \r
65 void () lvl1_sentry_atk2 = [ 2, lvl1_sentry_atk3 ]\r
66 {\r
67         ai_face ();\r
68         Sentry_Fire ();\r
69 };\r
70 \r
71 void () lvl1_sentry_atk3 = [ 0, lvl1_sentry_atk1 ]\r
72 {\r
73         ai_face ();\r
74 };\r
75 void () lvl2_sentry_atk3;\r
76 \r
77 void () lvl2_sentry_stand = [ 3, lvl2_sentry_stand ]\r
78 {\r
79         Sentry_Rotate ();\r
80 };\r
81 \r
82 void () lvl2_sentry_atk1 = [ 4, lvl2_sentry_atk2 ]\r
83 {\r
84         ai_face ();\r
85         if (((((self.enemy == world) || (self.enemy.health <= 0)) || !tfvisible (self.enemy)) || (self.enemy.has_disconnected == 1)))\r
86         {\r
87                 lvl2_sentry_stand ();\r
88         }\r
89         else\r
90         {\r
91                 if ((self.ammo_shells <= 0))\r
92                 {\r
93                         lvl2_sentry_stand ();\r
94                 }\r
95                 else\r
96                 {\r
97                         if ((Sentry_Fire () == 0))\r
98                         {\r
99                                 lvl2_sentry_atk3 ();\r
100                         }\r
101                 }\r
102         }\r
103 };\r
104 \r
105 void () lvl2_sentry_atk2 = [ 5, lvl2_sentry_atk3 ]\r
106 {\r
107         ai_face ();\r
108         Sentry_Fire ();\r
109 };\r
110 \r
111 void () lvl2_sentry_atk3 = [ 3, lvl2_sentry_atk1 ]\r
112 {\r
113         ai_face ();\r
114         Sentry_Fire ();\r
115 };\r
116 void () lvl3_sentry_atk3;\r
117 \r
118 void () lvl3_sentry_stand = [ 6, lvl3_sentry_stand ]\r
119 {\r
120         Sentry_Rotate ();\r
121 };\r
122 \r
123 void () lvl3_sentry_atk1 = [ 7, lvl3_sentry_atk2 ]\r
124 {\r
125         ai_face ();\r
126         if (((((self.enemy == world) || (self.enemy.health <= 0)) || !tfvisible (self.enemy)) || (self.enemy.has_disconnected == 1)))\r
127         {\r
128                 lvl3_sentry_stand ();\r
129         }\r
130         else\r
131         {\r
132                 if (((self.ammo_shells <= 0) && (self.ammo_rockets <= 0)))\r
133                 {\r
134                         lvl3_sentry_stand ();\r
135                 }\r
136                 else\r
137                 {\r
138                         if ((Sentry_Fire () == 0))\r
139                         {\r
140                                 lvl3_sentry_atk3 ();\r
141                         }\r
142                 }\r
143         }\r
144 };\r
145 \r
146 void () lvl3_sentry_atk2 = [ 8, lvl3_sentry_atk3 ]\r
147 {\r
148         ai_face ();\r
149         Sentry_Fire ();\r
150 };\r
151 \r
152 void () lvl3_sentry_atk3 = [ 6, lvl3_sentry_atk1 ]\r
153 {\r
154         ai_face ();\r
155         Sentry_Fire ();\r
156 };\r
157 \r
158 void () Sentry_Rotate =\r
159 {\r
160         local float ay;\r
161         local entity gunhead;\r
162 \r
163         CheckSentry (self);\r
164         if (Sentry_FindTarget ())\r
165         {\r
166                 return;\r
167         }\r
168         if ((self.heat == 0))\r
169         {\r
170                 self.ideal_yaw = self.waitmin;\r
171                 ChangeYaw ();\r
172                 ay = anglemod (self.angles_y);\r
173                 ay = rint (ay);\r
174                 if ((ay == rint (self.waitmin)))\r
175                 {\r
176                         CheckBelowBuilding (self.trigger_field);\r
177                         self.heat = 1;\r
178                         if ((random () < 0.1))\r
179                         {\r
180                                 sound (self, 3, "weapons/turridle.wav", 1, 1);\r
181                         }\r
182                 }\r
183         }\r
184         else\r
185         {\r
186                 self.ideal_yaw = self.waitmax;\r
187                 ChangeYaw ();\r
188                 ay = anglemod (self.angles_y);\r
189                 ay = rint (ay);\r
190                 if ((ay == rint (self.waitmax)))\r
191                 {\r
192                         CheckBelowBuilding (self.trigger_field);\r
193                         self.heat = 0;\r
194                 }\r
195         }\r
196 \r
197 /*      local entity oldself;\r
198         oldself = self;\r
199 //      self.barrel_ent.ideal_yaw = self.ideal_yaw;\r
200         self = self.barrel_ent;\r
201         self.ideal_yaw = anglemod(newmis.angles_z + 50);\r
202         ChangeYaw();\r
203         self = oldself;*/\r
204 \r
205 };\r
206 \r
207 float () Sentry_FindTarget =\r
208 {\r
209         local entity client;\r
210         local float r;\r
211         local float gotone;\r
212         local float loopc;\r
213 \r
214         r = 0;\r
215         loopc = 0;\r
216         gotone = 0;\r
217         client = findradius (self.origin + '20 0 0', 480);\r
218         while (((client != world) && (gotone != 1)))\r
219         {\r
220                 gotone = 1;\r
221                 if (!client)\r
222                 {\r
223                         gotone = 0;\r
224                 }\r
225                 if ((client == self))\r
226                 {\r
227                         gotone = 0;\r
228                 }\r
229                 if ((client.has_disconnected == 1))\r
230                 {\r
231                         gotone = 0;\r
232                 }\r
233                 if (!client.takedamage)\r
234                 {\r
235                         gotone = 0;\r
236                 }\r
237 /*              if (teamplay)\r
238                 {\r
239                         if (((client.team_no == self.team_no) && (self.team_no != 0)))\r
240                         {\r
241                                 gotone = 0;\r
242                         }\r
243                         // replace this with undercover as cloaking code\r
244                         if (((client.undercover_team == self.team_no) && (self.team_no != 0)))\r
245                         {\r
246                                 gotone = 0;\r
247                         }\r
248                 }*/\r
249 /*              if ((client == self.real_owner))\r
250                 {\r
251                         gotone = 0;\r
252                 }*/\r
253 /*              if (client.is_feigning)                         // we gonna add feigning?\r
254                 {\r
255                         gotone = 0;\r
256                 }*/\r
257                 if ((client.flags & 128))\r
258                 {\r
259                         gotone = 0;\r
260                 }\r
261                 if ((client.items & 524288))\r
262                 {\r
263                         gotone = 0;\r
264                 }\r
265                 if (!tfvisible (client))\r
266                 {\r
267                         gotone = 0;\r
268                 }\r
269                 r = range (client);\r
270                 if ((r == 3))\r
271                 {\r
272                         gotone = 0;\r
273                 }\r
274                 else\r
275                 {\r
276                         if (((r == 2) && !infront (client)))\r
277                         {\r
278                                 gotone = 0;\r
279                         }\r
280                 }\r
281                 if (!gotone)\r
282                 {\r
283                         client = client.chain;\r
284                 }\r
285         }\r
286         if (!gotone)\r
287         {\r
288                 return (0);\r
289         }\r
290         self.enemy = client;\r
291         Sentry_FoundTarget ();\r
292         return (1);\r
293 };\r
294 \r
295 void () Sentry_FoundTarget =\r
296 {\r
297         if (((self.ammo_shells > 0) || ((self.ammo_rockets > 0) && (self.weapon == 3))))\r
298         {\r
299                 sound (self, 2, "weapons/turrspot.wav", 1, 1);\r
300         }\r
301         Sentry_HuntTarget ();\r
302         if ((self.super_damage_finished < time))\r
303         {\r
304                 self.super_damage_finished = (time + 0.5);\r
305         }\r
306 };\r
307 \r
308 void () Sentry_HuntTarget =\r
309 {\r
310         self.goalentity = self.enemy;\r
311         if ((self.weapon == 1))\r
312         {\r
313                 self.think = lvl1_sentry_atk1;\r
314         }\r
315         else\r
316         {\r
317                 if ((self.weapon == 2))\r
318                 {\r
319                         self.think = lvl2_sentry_atk1;\r
320                 }\r
321                 else\r
322                 {\r
323                         self.think = lvl3_sentry_atk1;\r
324                 }\r
325         }\r
326         self.ideal_yaw = vectoyaw ((self.enemy.origin - self.origin));\r
327 \r
328         local vector temp;\r
329         temp = vectoangles(self.enemy.origin - self.origin);\r
330         self.barrel_ent.angles_x = -temp_x;\r
331 \r
332 /*      if (temp_x > 30)\r
333                 temp_x = 30;\r
334         if (temp_x < -30)\r
335                 temp_x = -30;*/\r
336 \r
337         /*zchange = ((self.enemy.origin - self.barrel_ent.origin) * .1);\r
338         if (zchange > 30)\r
339         {\r
340                 self.barrel_ent.angles_x = 30;\r
341         }\r
342         else if (zchange < 30)\r
343         {\r
344                 self.barrel_ent.angles_x = -30;\r
345         }\r
346         else\r
347         {\r
348                 self.barrel_ent.angles_x = zchange;\r
349         }*/\r
350 \r
351         //self.barrel_ent.angles_z = self.barrel_ent.ideal_yaw_z;\r
352 \r
353 //      self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);\r
354 //      self.ideal_yaw = anglemod(self.ideal_yaw);\r
355 \r
356         self.nextthink = (time + 0.1);\r
357         SUB_AttackFinished (1);\r
358 };\r
359 \r
360 void () Sentry_Pain =\r
361 {\r
362         self.real_owner.StatusRefreshTime = (time + 0.2);\r
363 };\r
364 \r
365 void () Sentry_Explode =\r
366 {\r
367 /*      ThrowGib ("progs/tgib1.mdl", -70);                      // reokace with throw metal chunks code.\r
368         ThrowGib ("progs/tgib2.mdl", -70);\r
369         ThrowGib ("progs/tgib3.mdl", -70);*/\r
370         if ((self.real_owner.has_disconnected != 1))\r
371         {\r
372                 deathmsg = 38;\r
373                 T_RadiusDamage (self, self.real_owner, (75 + (self.ammo_rockets * 8)), self);\r
374         }\r
375         if ((self.classname == "building_sentrygun_base"))\r
376         {\r
377                 if (self.oldenemy)\r
378                 {\r
379                         dremove (self.oldenemy);\r
380                 }\r
381         }\r
382         else\r
383         {\r
384                 dremove (self.trigger_field);\r
385         }\r
386         WriteByte (0, 23);\r
387         WriteByte (0, 3);\r
388         WriteCoord (0, self.origin_x);\r
389         WriteCoord (0, self.origin_y);\r
390         WriteCoord (0, self.origin_z);\r
391         BecomeExplosion ();\r
392 };\r
393 \r
394 void () Sentry_Die =\r
395 {\r
396         sprint (self.real_owner, "Your sentry gun was destroyed.\n");\r
397         self.real_owner.has_sentry = 0;\r
398         self.think = Sentry_Explode;\r
399         self.nextthink = (time + 0.1);\r
400 };\r
401 \r
402 void W_Sentry_Fire(vector org, vector vel, float damage)\r
403 {\r
404         entity spike;\r
405         spike = spawn ();\r
406         spike.enemy = self.owner;\r
407         spike.owner = self;\r
408         spike.classname = "spike";\r
409 \r
410         spike.movetype = MOVETYPE_FLY;\r
411         spike.solid = SOLID_BBOX;\r
412         setmodel(spike, "models/plasmatrail.mdl");\r
413         setsize(spike, '0 0 0', '0 0 0');\r
414         setorigin(spike, org);\r
415 \r
416         spike.dmg = damage;\r
417 \r
418         spike.nextthink = time + 3 + random()*0.5;\r
419         spike.think = SUB_Remove;\r
420         spike.touch = W_NailGrenade_Spike_Poke;\r
421         spike.velocity = vel * 6;\r
422         spike.angles = vectoangles (spike.velocity);\r
423 //      spike.scale = 0.75;\r
424 \r
425 //      setattachment(spike, self.barrel_ent, "tag_body_barrel");\r
426 }\r
427 \r
428 float () Sentry_Fire =\r
429 {\r
430         self.ammo_shells = 50;          //temp\r
431 \r
432         local vector dir;\r
433 \r
434         dir = (self.enemy.origin - self.origin);\r
435         if ((((self.ideal_yaw - anglemod (self.angles_y)) < -10) || ((self.ideal_yaw - anglemod (self.angles_y)) > 10)))\r
436         {\r
437                 return (0);\r
438         }\r
439         if ((((self.weapon == 3) && (self.ammo_rockets > 0)) && (self.super_damage_finished < time)))\r
440         {\r
441                 Sentry_MuzzleFlash ();\r
442                 sound (self, 1, "weapons/rocket1i.wav", 1, 1);\r
443                 newmis = spawn ();\r
444                 newmis.owner = self;\r
445                 newmis.movetype = 9;\r
446                 newmis.solid = 2;\r
447                 newmis.velocity = (normalize ((self.enemy.origin - self.origin)) * 800);\r
448                 newmis.angles = vectoangles (newmis.velocity);\r
449                 newmis.weapon = 34;\r
450 //              newmis.touch = T_MissileTouch;\r
451                 newmis.touch = W_Rocket_Touch;\r
452                 newmis.nextthink = (time + 5);\r
453                 newmis.think = SUB_Remove;\r
454                 setmodel (newmis, "progs/missile.mdl");\r
455                 setsize (newmis, '0 0 0', '0 0 0');\r
456                 setorigin (newmis, ((self.origin + (v_forward * 8)) + '0 0 16'));\r
457                 self.super_damage_finished = (time + 3);\r
458                 self.ammo_rockets = (self.ammo_rockets - 1);\r
459                 if ((self.ammo_rockets == 10))\r
460                 {\r
461                         sprint (self.real_owner, "Sentry Gun is low on rockets.\n");\r
462                 }\r
463         }\r
464         self.ammo_shells = (self.ammo_shells - 1);\r
465         if ((self.ammo_shells < 0))\r
466         {\r
467                 self.ammo_shells = 0;\r
468                 return (0);\r
469         }\r
470         Sentry_MuzzleFlash ();\r
471         sound (self, 1, "weapons/sniper.wav", 1, 1);\r
472         deathmsg = 27;\r
473 \r
474         local float barrel_tag;\r
475         local vector fire_from;\r
476 \r
477 //      barrel_tag = gettagindex (self.barrel_ent, "tag_bullet");\r
478         barrel_tag = gettagindex (self.barrel_ent, "tag_barrel_bullet1");\r
479         fire_from = gettaginfo (self.barrel_ent, barrel_tag);\r
480 \r
481 \r
482 /*      bprint (ftos(barrel_tag));\r
483         bprint ("   \n");\r
484         bprint (vtos(fire_from));\r
485         bprint ("\n");*/\r
486 \r
487 //fire_from = fire_from + v_forward + v_up + v_right;\r
488 //void fireBullet (vector start, vector dir, float spread, float damage, float dtype, float tracer);\r
489         //(entity targ, entity inflictor, entity attacker, float damage) T_Damage\r
490 //      fireBullet (fire_from, dir, .1, 2, 666, 1);\r
491 //      T_Damage(self.enemy, self, self, 4);\r
492 //fire_from = fire_from + self.barrel_ent.view_ofs + v_forward + v_right + v_up;\r
493 \r
494 local entity testent;\r
495 local entity testent2;\r
496 \r
497 testent = spawn ();\r
498 testent.movetype = 0;\r
499 testent.solid = SOLID_BBOX;\r
500 setmodel(testent, "models/sentry/bullet.MD3");\r
501 //setorigin(testent, fire_from);\r
502 setattachment(testent, self.barrel_ent, "tag_barrel_bullet1");\r
503 \r
504 barrel_tag = gettagindex (testent, "");\r
505 fire_from = gettaginfo (testent, barrel_tag);\r
506 dir = (self.enemy.origin - fire_from);\r
507 \r
508 \r
509 //barrel_tag = gettagindex (testent, "tag_bullet");\r
510 //fire_from = gettaginfo (testent, testent.tag_index);\r
511 //dir = (self.enemy.origin - fire_from);\r
512 \r
513 /*testent2 = spawn ();\r
514 testent2.movetype = 0;\r
515 testent2.solid = SOLID_BBOX;\r
516 //testent2.scale = 5;\r
517 setmodel(testent2, "models/plasmatrail.mdl");\r
518 setorigin(testent2, fire_from);*/\r
519         dir = self.enemy.origin - self.origin;\r
520         makevectors(self.origin + dir);\r
521 \r
522         fire_from = self.origin + v_forward * 20;\r
523 \r
524 \r
525         W_Sentry_Fire(fire_from, dir, 4);\r
526 \r
527 //      FireBullets (4, dir, '0.1 0.1 0');\r
528         if (((self.ammo_shells == 0) && (random () < 0.1)))\r
529         {\r
530                 sprint (self.real_owner, "Sentry Gun is out of shells.\n");\r
531         }\r
532         else\r
533         {\r
534                 if ((self.ammo_shells == 20))\r
535                 {\r
536                         sprint (self.real_owner, "Sentry Gun is low on shells.\n");\r
537                 }\r
538         }\r
539         if ((((self.ammo_rockets == 0) && (self.weapon == 3)) && (random () < 0.1)))\r
540         {\r
541                 sprint (self.real_owner, "Sentry Gun is out of rockets.\n");\r
542         }\r
543         return (1);\r
544 };\r
545 \r
546 void () Sentry_MuzzleFlash =\r
547 {\r
548         self.effects = (self.effects | 2);\r
549 };\r