]> icculus.org git repositories - divverent/nexuiz.git/blob - attic/TeamNexuiz/game/gamec/spy.c
now menu qc respects g_campaign_name
[divverent/nexuiz.git] / attic / TeamNexuiz / game / gamec / spy.c
1 \r
2 void SpyDecloak()\r
3 {\r
4         if(!self.special_active)\r
5                 return;\r
6         self.special_active = 0;\r
7         ResetPlayerModel(self);\r
8         if(self.health < 2)\r
9                 self.alpha = 0;\r
10         else\r
11                 self.alpha = 0.1;\r
12 }\r
13 \r
14 void SpyCloak()\r
15 {\r
16         if(self.health <= cvar("g_balance_spy_cloak_min_health"))\r
17         {\r
18                 sprint(self, "not healthy enough\n");\r
19                 return;\r
20         }\r
21 \r
22         self.health = self.health - cvar("g_balance_spy_cloak_cost_start");\r
23 \r
24         self.alpha = 1;\r
25 \r
26         self.special_active = 1;\r
27         self.special_time = time;\r
28 }\r
29 \r
30 // From TF2.5(tm)\r
31 float(vector veca, vector vecb) crossproduct = \r
32 {\r
33         local float result;\r
34         result = veca_x * vecb_y - vecb_x * veca_y;\r
35         return result;\r
36 };\r
37 \r
38 void SpyDisarm ()\r
39 {\r
40         local vector source;\r
41         local vector def;\r
42 \r
43 //      self.currentammo = 0;\r
44         makevectors (self.v_angle);\r
45         source = (self.origin + '0 0 16');\r
46         traceline (source, (source + (v_forward * 64)), 0, self);\r
47         if ((trace_fraction == 1))\r
48         {\r
49                 return;\r
50         }\r
51         makevectors (trace_ent.v_angle);\r
52         def = v_right;\r
53         makevectors (self.v_angle);\r
54         if (trace_ent.classname == "player" && trace_ent.health > 0)\r
55         {\r
56                 if (crossproduct (def, v_forward) > 0)\r
57                 {\r
58                         other.currentammo = 0;\r
59                         sprint(other, "You have been disarmed!\n");\r
60                         other.ammo_shells = 0;\r
61                         other.ammo_cells = 0;\r
62                         other.ammo_rockets = 0;\r
63                         other.ammo_metal = 0;\r
64                         other.ammo_nails = 0;\r
65                         other.no_grenades_1 = 0;\r
66                         other.no_grenades_2 = 0;\r
67                         self.grenade_time = time + 10;\r
68                 }\r
69                 else\r
70                 {\r
71                         sprint(self, "You can only disarm someone from behind\n");\r
72                 }\r
73         }\r
74 };\r
75 \r
76 void SpySpecial()\r
77 {\r
78         if(self.special_active)\r
79         {\r
80                 SpyDecloak();\r
81                 return;\r
82         }\r
83         SpyCloak();\r
84 }\r
85 \r
86 void SpyGrenade(float req)\r
87 {\r
88         SpyDecloak();\r
89         if(req == WR_GRENADE1)\r
90         {\r
91 //              if( W_ThrowGrenade(W_NailGrenade) )\r
92 //                      self.grenade_time = time + cvar("g_balance_grenade_nail_refire");\r
93                 SpyDisarm();\r
94         }\r
95         else if(req == WR_GRENADE2)\r
96         {\r
97         }\r
98 }\r
99 \r
100 void SpyCloakFlicker(entity pl)\r
101 {\r
102         if(pl.class != CLASS_SPY)\r
103                 return;\r
104         if(!pl.special_active)\r
105                 return;\r
106 \r
107         pl.alpha = bound(0.001, pl.alpha + 0.3 + random()*0.2, 1);\r
108 }\r
109 \r
110 void SpyPreThink()\r
111 {\r
112         local vector m1, m2;\r
113         local float desired_alpha, spd, min_health;\r
114 \r
115         if(self.special_active) // am I cloaked?\r
116         {\r
117                 min_health = cvar("g_balance_spy_cloak_min_health");\r
118                 if(self.health < min_health || self.onfire != world || self.poison_damage)\r
119                 {// out of health\r
120                         SpyDecloak();\r
121                         return;\r
122                 }\r
123 \r
124                 spd = vlen(self.velocity);\r
125                 spd = spd - self.speed*1.15; // spy can stay cloaked up to his max speed (plus some extra to keep from flickering on slopes), but any faster and he starts to show...\r
126                 if(spd <= 0)\r
127                         desired_alpha = 0;\r
128                 else\r
129                 {\r
130                         desired_alpha = bound(0, \r
131                                 cvar("g_balance_spy_move_alpha")*spd / self.speed, \r
132                                 cvar("g_balance_spy_move_alpha_max"));\r
133                 }\r
134 \r
135 \r
136                 // adjust alpha to reflect new value\r
137                 if(self.alpha < desired_alpha)\r
138                         self.alpha = bound(0.001, self.alpha + 0.1, 1);\r
139                 else if(self.alpha > desired_alpha)\r
140                         self.alpha = bound(0.001, self.alpha - 0.1, 1);\r
141 \r
142                 // take health/armor cost\r
143                 self.health = bound(min_health,\r
144                         self.health - cvar("g_balance_spy_cloak_cost_upkeeph") * frametime,\r
145                         self.health);\r
146                 // take health/armor cost\r
147                 self.armorvalue = bound(0,\r
148                         self.armorvalue - cvar("g_balance_spy_cloak_cost_upkeepa") * frametime,\r
149                         self.armorvalue);\r
150 \r
151                 if(self.health <= min_health)\r
152                 {// out of health\r
153                         SpyDecloak();\r
154                         return;\r
155                 }\r
156 \r
157 \r
158                 self.special_time = time + 0.1;\r
159 \r
160                 // if I'm fully cloaked, set my model to nothing\r
161                 if(self.alpha < 0.01 && self.model != "")\r
162                 {\r
163                         m1 = self.mins;\r
164                         m2 = self.maxs;\r
165                         setmodel (self, "");\r
166                         setsize (self, m1, m2);\r
167                 }\r
168                 else if(self.alpha > 0.01 && self.model == "")\r
169                 {\r
170                         ResetPlayerModel(self);\r
171                 }\r
172 \r
173                 self.alpha = bound(0.001, self.alpha, 1.0);\r
174 \r
175                 // also cloak weapons\r
176                 self.weaponentity.alpha = 1 - 0.5*(1 - self.alpha);//self.alpha + 0.1;\r
177                 self.exteriorweaponentity.alpha = self.alpha; //self.weaponentity.alpha;\r
178         }\r
179         else\r
180         {// decloaked\r
181                 if(self.alpha != 0)// && self.alpha != 1)\r
182                 {// not fully visible yet, keep phasing back in\r
183                         self.alpha = self.alpha + 0.1;\r
184                         self.weaponentity.alpha = 1 - (1 - self.alpha)*0.5;\r
185                         if(self.alpha > 1)\r
186                                 self.alpha = self.weaponentity.alpha = 0;\r
187                 }\r
188                 //else\r
189                 //      self.weaponentity.alpha = 0;\r
190         }\r
191 \r
192 \r
193         \r
194         /*      if(self.special_active) // am I cloaked?\r
195         {\r
196                 if(self.health < 10)\r
197                 {// out of health\r
198                         SpyDecloak();\r
199                 }\r
200                 else if(self.model != "" && self.special_time <= time)\r
201                 {// not fully cloaked yet, but working on it\r
202                         self.alpha = self.alpha - 0.1;\r
203                         self.weaponentity.alpha = 1 - (1 - self.alpha)*0.5;//self.alpha + 0.1;\r
204                         self.special_time = time + 0.1;\r
205                         if(self.alpha < 0.1)\r
206                         {\r
207                                 m1 = self.mins;\r
208                                 m2 = self.maxs;\r
209                                 setmodel (self, "");\r
210                                 setsize (self, m1, m2);\r
211                                 self.special_time = time + 1;\r
212                         }\r
213                 }\r
214                 else if(self.special_time <= time)\r
215                 {// fully cloaked, take health cost\r
216                         self.alpha = self.weaponentity.alpha = 0.25;\r
217                         self.special_time = time + 1;\r
218 \r
219                         // reduce health & armor while cloaked\r
220                         self.health = self.health - 2;//3;\r
221                         if(self.armorvalue > 2)//3)\r
222                                 self.armorvalue = self.armorvalue - 2;//3;\r
223                 }\r
224         }\r
225         else\r
226         {// decloaked\r
227                 if(self.alpha != 0 && self.alpha != 1)\r
228                 {// not fully visible yet, keep phasing back in\r
229                         self.alpha = self.alpha + 0.1;\r
230                         self.weaponentity.alpha = 1 - (1 - self.alpha)*0.5;\r
231                         if(self.alpha > 1)\r
232                                 self.alpha = 0;\r
233                 }\r
234                 else\r
235                         self.weaponentity.alpha = 0;\r
236         }\r
237 \r
238         self.exteriorweaponentity.alpha = self.weaponentity.alpha;*/\r
239 }\r
240 \r
241 void SpyPostThink()\r
242 {\r
243 }\r
244 \r
245 void BecomeSpy(float portion)\r
246 {\r
247         self.max_health = cvar("g_balance_class_spy_health") * portion;\r
248 \r
249         self.max_armor = cvar("g_balance_class_spy_armor") * portion;\r
250 \r
251         self.mass = cvar("g_balance_class_spy_mass");\r
252 \r
253         SetPlayerSpeed(self);\r
254 \r
255         self.items = IT_WEP1 | IT_WEP2 | IT_WEP3 | IT_WEP4;\r
256         self.switchweapon = WEP2;\r
257         self.ammo_shells = floor(20 * portion);\r
258         self.ammo_nails = floor(50 * portion);\r
259         self.ammo_rockets = floor(3 * portion);\r
260         self.ammo_cells = floor(0 * portion);\r
261         self.playerclass = TF_CLASS_SPY;                // TF P.C.\r
262         SetMaxAmmoFor (2);\r
263         // fixme: also have off-hand grenade, different for each class\r
264         // where to do that?\r
265 }\r
266 \r
267 /*void () Switch_View_Think =\r
268 {\r
269         if (self.health < 1)\r
270                 dremove(self);\r
271         self.owner.view_ofs = self.view_ofs * self.health;\r
272 \r
273         self.health = self.health - 1;\r
274         self.nextthink = time;\r
275 \r
276 };\r
277 \r
278 void (vector vchange) Switch_View =\r
279 {\r
280         local entity viewchanger;\r
281         local vector changevec;\r
282 \r
283         changevec = ((self.view_ofs - vchange) * .10);\r
284 \r
285         viewchanger = spawn();\r
286         viewchanger.think = Switch_View_Think;\r
287         viewchanger.nextthink = time;\r
288         viewchanger.owner = self;\r
289         viewchanger.view_ofs = changevec;\r
290         viewchanger.health = 10;\r
291 };*/\r
292 \r
293 void () Switch_View_Think =\r
294 {\r
295         if (time > self.button1 + self.health)\r
296                 dremove(self);\r
297         self.owner.view_ofs = self.owner.view_ofs - ((self.view_ofs * frametime) * (1 / self.health));\r
298         self.nextthink = time;\r
299 };\r
300 void (vector vchange, float change_spd) Switch_View =\r
301 {\r
302         local entity viewchanger;\r
303         local vector changevec;\r
304         changevec = self.view_ofs - vchange;\r
305         viewchanger = spawn();\r
306         viewchanger.think = Switch_View_Think;\r
307         viewchanger.nextthink = time;\r
308         viewchanger.owner = self;\r
309         viewchanger.view_ofs = changevec;\r
310         viewchanger.health = change_spd;\r
311         viewchanger.button1 = time;\r
312 }\r
313 \r
314 // Spy Feign\r
315 void () TeamNexuiz_Feign =\r
316 {\r
317         if (self.playerclass != TF_CLASS_SPY)\r
318                 return;\r
319         if ((self.reload_time + .25) > time)\r
320                 return;\r
321         if (self.health <= 0)\r
322                 return;\r
323         if (!(self.flags & FL_ONGROUND))\r
324         {\r
325                 sprint(self, "You cannot feign mid-air\n");\r
326                 return;\r
327         }\r
328         local entity at_spot;\r
329         local float intgr;\r
330 \r
331         self.velocity = '0 0 0';\r
332         if (self.is_feigning == 1)\r
333         {\r
334                 at_spot = findradius(self.origin, 64);          // search for someone to make sure no-one is standing on\r
335                 intgr = 1;                                                                      //// the player when he tries to get up\r
336                 while (at_spot != world)\r
337                 {\r
338                         if (at_spot.classname == "player" && at_spot.is_dead != 1 && at_spot != self)\r
339                         {\r
340                                 intgr = 0;\r
341                         }\r
342                         at_spot = at_spot.chain;\r
343                 }\r
344                 if (intgr == 0)\r
345                 {\r
346                         sprint(self, "You can't get up while someone is standing on you.\n");\r
347                         return;\r
348                 }\r
349                 else\r
350                 {\r
351                         self.is_feigning = 0;\r
352                         setsize(self, PL_MIN, PL_MAX);\r
353                         Switch_View(PL_VIEW_OFS, .3);\r
354                         TeamNexuiz_GunUp();\r
355                 }\r
356         }\r
357         else\r
358         {\r
359                 self.is_feigning = 1;\r
360                 TeamFortress_ThrowGrenade();            // Toss any primed grenades while feigning\r
361                 setsize(self, '-16 -16 -24', '16 16 5');\r
362                 Switch_View(PL_FEIGN_VIEW_OFS, .3);\r
363                 TeamNexuiz_GunDown();\r
364         }\r
365 };