]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/w_uzi.qc
Return ammo code I previously removed from the UZI. I don't know what it was there...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / w_uzi.qc
1 #ifdef REGISTER_WEAPON
2 REGISTER_WEAPON(UZI, w_uzi, IT_NAILS, 3, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_MID, "uzi", "uzi", _("Machine Gun"))
3 #else
4 #ifdef SVQC
5
6 .float uzi_load;
7
8 void W_UZI_SetAmmoCounter()
9 {
10         // set clip_load to the weapon we have switched to, if the gun uses reloading
11         if(!autocvar_g_balance_uzi_reload_ammo)
12                 self.clip_load = 0; // also keeps crosshair ammo from displaying
13         else
14         {
15                 self.clip_load = self.uzi_load;
16                 self.clip_size = autocvar_g_balance_uzi_reload_ammo; // for the crosshair ammo display
17         }
18 }
19
20 void W_UZI_ReloadedAndReady()
21 {
22         float t;
23
24         // now do the ammo transfer
25         self.clip_load = self.old_clip_load; // restore the ammo counter, in case we still had ammo in the weapon before reloading
26         while(self.clip_load < autocvar_g_balance_uzi_reload_ammo && self.ammo_nails) // make sure we don't add more ammo than we have
27         {
28                 self.clip_load += 1;
29                 self.ammo_nails -= 1;
30         }
31         self.uzi_load = self.clip_load;
32
33         t = ATTACK_FINISHED(self) - autocvar_g_balance_uzi_reload_time - 1;
34         ATTACK_FINISHED(self) = t;
35         w_ready();
36 }
37
38 void W_UZI_Reload()
39 {
40         // return if reloading is disabled for this weapon
41         if(!autocvar_g_balance_uzi_reload_ammo)
42                 return;
43
44         if(!W_ReloadCheck(self.ammo_nails, min(max(autocvar_g_balance_uzi_sustained_ammo, autocvar_g_balance_uzi_first_ammo), autocvar_g_balance_uzi_burst_ammo)))
45                 return;
46
47         float t;
48
49         sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
50
51         t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_uzi_reload_time + 1;
52         ATTACK_FINISHED(self) = t;
53
54         weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_uzi_reload_time, W_UZI_ReloadedAndReady);
55
56         self.old_clip_load = self.clip_load;
57         self.clip_load = -1;
58 }
59
60 // leilei's fancy muzzleflash stuff
61 void UZI_Flash_Go() 
62 {       
63         self.frame = self.frame + 2;
64         self.scale = self.scale * 0.5;
65         self.alpha = self.alpha - 0.25;
66         self.nextthink = time + 0.05;
67
68         if (self.alpha <= 0)
69         {
70                 self.think = SUB_Remove;
71                 self.nextthink = time;
72                 self.owner.muzzle_flash = world;
73                 return;
74         }
75         
76 }
77
78 void UziFlash()
79 {       
80         if (self.muzzle_flash == world)
81                 self.muzzle_flash = spawn();    
82         
83         // muzzle flash for 1st person view
84         setmodel(self.muzzle_flash, "models/uziflash.md3"); // precision set below
85         
86         self.muzzle_flash.scale = 0.75;
87         self.muzzle_flash.think = UZI_Flash_Go;
88         self.muzzle_flash.nextthink = time + 0.02;
89         self.muzzle_flash.frame = 2;
90         self.muzzle_flash.alpha = 0.75;
91         self.muzzle_flash.angles_z = random() * 180;
92         self.muzzle_flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
93         self.muzzle_flash.owner = self;
94 }
95
96 void W_UZI_Attack (float deathtype)
97 {
98         W_SetupShot (self, autocvar_g_antilag_bullets && autocvar_g_balance_uzi_speed >= autocvar_g_antilag_bullets, 0, "weapons/uzi_fire.wav", CHAN_WEAPON, ((self.misc_bulletcounter == 1) ? autocvar_g_balance_uzi_first_damage : autocvar_g_balance_uzi_sustained_damage));
99         if (!g_norecoil)
100         {
101                 self.punchangle_x = random () - 0.5;
102                 self.punchangle_y = random () - 0.5;
103         }
104
105         // this attack_finished just enforces a cooldown at the end of a burst
106         ATTACK_FINISHED(self) = time + autocvar_g_balance_uzi_first_refire * W_WeaponRateFactor();
107
108         if (self.misc_bulletcounter == 1)
109                 fireBallisticBullet(w_shotorg, w_shotdir, autocvar_g_balance_uzi_first_spread, autocvar_g_balance_uzi_speed, 5, autocvar_g_balance_uzi_first_damage, 0, autocvar_g_balance_uzi_first_force, deathtype, 0, 1, autocvar_g_balance_uzi_bulletconstant);
110         else
111                 fireBallisticBullet(w_shotorg, w_shotdir, autocvar_g_balance_uzi_sustained_spread, autocvar_g_balance_uzi_speed, 5, autocvar_g_balance_uzi_sustained_damage, 0, autocvar_g_balance_uzi_sustained_force, deathtype, 0, 1, autocvar_g_balance_uzi_bulletconstant);
112         endFireBallisticBullet();
113
114         pointparticles(particleeffectnum("uzi_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
115
116         UziFlash();
117         W_AttachToShotorg(self.muzzle_flash, '5 0 0');
118
119         // casing code
120         if (autocvar_g_casings >= 2)
121                 SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self);
122
123         // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
124         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
125         {
126                 if(autocvar_g_balance_uzi_reload_ammo)
127                 {
128                         if (self.misc_bulletcounter == 1)
129                                 self.clip_load -= autocvar_g_balance_uzi_first_ammo;
130                         else
131                                 self.clip_load -= autocvar_g_balance_uzi_sustained_ammo;
132                         self.uzi_load = self.clip_load;
133                 }
134                 else
135                 {
136                         if (self.misc_bulletcounter == 1)
137                                 self.ammo_nails -= autocvar_g_balance_uzi_first_ammo;
138                         else
139                                 self.ammo_nails -= autocvar_g_balance_uzi_sustained_ammo;
140                 }
141         }
142 }
143
144 // weapon frames
145 void uzi_fire1_02()
146 {
147         if(self.weapon != self.switchweapon) // abort immediately if switching
148         {
149                 w_ready();
150                 return;
151         }
152         if (self.BUTTON_ATCK)
153         {
154                 if (!weapon_action(self.weapon, WR_CHECKAMMO2))
155                 {
156                         W_SwitchWeapon_Force(self, w_getbestweapon(self));
157                         w_ready();
158                         return;
159                 }
160                 self.misc_bulletcounter = self.misc_bulletcounter + 1;
161                 W_UZI_Attack(WEP_UZI);
162                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, uzi_fire1_02);
163         }
164         else
165                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, w_ready);
166 }
167
168
169 void uzi_mode1_fire_auto()
170 {
171         float uzi_spread;
172
173         // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
174         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
175         {
176                 if(autocvar_g_balance_uzi_reload_ammo)
177                 {
178                         self.clip_load -= autocvar_g_balance_uzi_sustained_ammo;
179                         self.uzi_load = self.clip_load;
180                 }
181                 else
182                         self.ammo_nails -= autocvar_g_balance_uzi_sustained_ammo;
183         }
184         
185         if (self.BUTTON_ATCK)
186                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, uzi_mode1_fire_auto);
187         else
188         {
189                 ATTACK_FINISHED(self) = time + autocvar_g_balance_uzi_first_refire * W_WeaponRateFactor();
190                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, w_ready);
191                 return;
192         }
193
194         if (!weapon_action(self.weapon, WR_CHECKAMMO1))
195         {
196                 W_SwitchWeapon_Force(self, w_getbestweapon(self));
197                 w_ready();
198                 return;
199         }
200         
201         W_SetupShot (self, autocvar_g_antilag_bullets && autocvar_g_balance_uzi_speed >= autocvar_g_antilag_bullets, 0, "weapons/uzi_fire.wav", CHAN_WEAPON, autocvar_g_balance_uzi_sustained_damage);
202         if (!g_norecoil)
203         {
204                 self.punchangle_x = random () - 0.5;
205                 self.punchangle_y = random () - 0.5;
206         }
207         
208         uzi_spread = bound(autocvar_g_balance_uzi_spread_min, autocvar_g_balance_uzi_spread_min + (autocvar_g_balance_uzi_spread_add * self.misc_bulletcounter), autocvar_g_balance_uzi_spread_max);
209         fireBallisticBullet(w_shotorg, w_shotdir, uzi_spread, autocvar_g_balance_uzi_speed, 5, autocvar_g_balance_uzi_sustained_damage, 0, autocvar_g_balance_uzi_sustained_force, WEP_UZI, 0, 1, autocvar_g_balance_uzi_bulletconstant);
210         endFireBallisticBullet();
211         
212         self.misc_bulletcounter = self.misc_bulletcounter + 1;
213         
214         pointparticles(particleeffectnum("uzi_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
215
216         UziFlash();
217         W_AttachToShotorg(self.muzzle_flash, '5 0 0');
218         
219         if (autocvar_g_casings >= 2) // casing code
220                 SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self);
221 }
222
223 void uzi_mode1_fire_burst()
224 {
225         W_SetupShot (self, autocvar_g_antilag_bullets && autocvar_g_balance_uzi_speed >= autocvar_g_antilag_bullets, 0, "weapons/uzi_fire.wav", CHAN_WEAPON, autocvar_g_balance_uzi_sustained_damage);
226         if (!g_norecoil)
227         {
228                 self.punchangle_x = random () - 0.5;
229                 self.punchangle_y = random () - 0.5;
230         }
231         
232         fireBallisticBullet(w_shotorg, w_shotdir, autocvar_g_balance_uzi_burst_spread, autocvar_g_balance_uzi_speed, 5, autocvar_g_balance_uzi_sustained_damage, 0, autocvar_g_balance_uzi_sustained_force, WEP_UZI, 0, 1, autocvar_g_balance_uzi_bulletconstant);
233         endFireBallisticBullet();
234         
235         
236         pointparticles(particleeffectnum("uzi_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
237
238         UziFlash();
239         W_AttachToShotorg(self.muzzle_flash, '5 0 0');
240         
241         if (autocvar_g_casings >= 2) // casing code
242                 SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self);
243
244         self.misc_bulletcounter = self.misc_bulletcounter + 1;
245         if (self.misc_bulletcounter == 0)
246         {
247                 ATTACK_FINISHED(self) = time + autocvar_g_balance_uzi_burst_refire2 * W_WeaponRateFactor();
248                 weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_uzi_burst_animtime, w_ready);
249         }
250         else
251         {
252                 weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_uzi_burst_refire, uzi_mode1_fire_burst);
253         }
254                 
255 }
256
257 void spawnfunc_weapon_machinegun(); // defined in t_items.qc
258
259 float w_uzi(float req)
260 {
261         if (req == WR_AIM)
262                 if(vlen(self.origin-self.enemy.origin) < 3000 - bound(0, skill, 10) * 200)
263                         self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, FALSE);
264                 else
265                 {
266                         self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, FALSE);
267                 }
268         else if (req == WR_THINK)
269         {
270                 if(autocvar_g_balance_uzi_reload_ammo && self.clip_load < min(max(autocvar_g_balance_uzi_sustained_ammo, autocvar_g_balance_uzi_first_ammo), autocvar_g_balance_uzi_burst_ammo)) // forced reload
271                         W_UZI_Reload();
272                 else if(autocvar_g_balance_uzi_mode == 1)
273                 {
274                         if (self.BUTTON_ATCK)
275                         if (weapon_prepareattack(0, 0))
276                         {                               
277                                 self.misc_bulletcounter = 0;
278                                 uzi_mode1_fire_auto();
279                         }
280                         
281                         if(self.BUTTON_ATCK2)
282                         if(weapon_prepareattack(1, 0))
283                         {
284                                 if (!weapon_action(self.weapon, WR_CHECKAMMO2))
285                                 {
286                                         W_SwitchWeapon_Force(self, w_getbestweapon(self));
287                                         w_ready();
288                                         return FALSE;
289                                 }
290
291                                 // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
292                                 if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
293                                 {
294                                         if(autocvar_g_balance_uzi_reload_ammo)
295                                         {
296                                                 self.clip_load -= autocvar_g_balance_uzi_burst_ammo;
297                                                 self.uzi_load = self.clip_load;
298                                         }
299                                         else
300                                                 self.ammo_nails -= autocvar_g_balance_uzi_burst_ammo;
301                                 }
302
303                                 self.misc_bulletcounter = autocvar_g_balance_uzi_burst * -1;
304                                 uzi_mode1_fire_burst();
305                         }
306                 }
307                 else
308                 {
309                         
310                         if (self.BUTTON_ATCK)
311                         if (weapon_prepareattack(0, 0))
312                         {
313                                 self.misc_bulletcounter = 1;
314                                 W_UZI_Attack(WEP_UZI); // sets attack_finished
315                                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, uzi_fire1_02);
316                         }
317
318                         if (self.BUTTON_ATCK2 && autocvar_g_balance_uzi_first)
319                         if (weapon_prepareattack(1, 0))
320                         {
321                                 self.misc_bulletcounter = 1;
322                                 W_UZI_Attack(WEP_UZI | HITTYPE_SECONDARY); // sets attack_finished
323                                 weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_uzi_first_refire, w_ready);
324                         }
325                 }
326         if(self.wish_reload)
327         {
328             if(self.switchweapon == self.weapon)
329             {
330                 if(self.weaponentity.state == WS_READY)
331                 {
332                     self.wish_reload = 0;
333                     W_UZI_Reload();
334                 }
335             }
336         }
337         }
338         else if (req == WR_PRECACHE)
339         {
340                 precache_model ("models/uziflash.md3");
341                 precache_model ("models/weapons/g_uzi.md3");
342                 precache_model ("models/weapons/v_uzi.md3");
343                 precache_model ("models/weapons/h_uzi.iqm");
344                 precache_sound ("weapons/uzi_fire.wav");
345                 precache_sound ("weapons/reload.wav");
346         }
347         else if (req == WR_SETUP)
348         {
349                 weapon_setup(WEP_UZI);
350                 W_UZI_SetAmmoCounter();
351         }
352         else if (req == WR_CHECKAMMO1)
353         {
354                 if(autocvar_g_balance_uzi_mode == 1)
355                         return self.ammo_nails >= autocvar_g_balance_uzi_sustained_ammo;
356                 else
357                         return self.ammo_nails >= autocvar_g_balance_uzi_first_ammo;
358         }
359         else if (req == WR_CHECKAMMO2)
360         {
361                 if(autocvar_g_balance_uzi_mode == 1)
362                         return self.ammo_nails >= autocvar_g_balance_uzi_burst_ammo;
363                 else
364                         return self.ammo_nails >= autocvar_g_balance_uzi_first_ammo;
365         }
366         else if (req == WR_RELOAD)
367         {
368                 W_UZI_Reload();
369         }
370         return TRUE;
371 };
372 #endif
373 #ifdef CSQC
374 float w_uzi(float req)
375 {
376         if(req == WR_IMPACTEFFECT)
377         {
378                 vector org2;
379                 org2 = w_org + w_backoff * 2;
380                 pointparticles(particleeffectnum("machinegun_impact"), org2, w_backoff * 1000, 1);
381                 if(!w_issilent)
382                         if(w_random < 0.05)
383                                 sound(self, CHAN_PROJECTILE, "weapons/ric1.wav", VOL_BASE, ATTN_NORM);
384                         else if(w_random < 0.1)
385                                 sound(self, CHAN_PROJECTILE, "weapons/ric2.wav", VOL_BASE, ATTN_NORM);
386                         else if(w_random < 0.2)
387                                 sound(self, CHAN_PROJECTILE, "weapons/ric3.wav", VOL_BASE, ATTN_NORM);
388         }
389         else if(req == WR_PRECACHE)
390         {
391                 precache_sound("weapons/ric1.wav");
392                 precache_sound("weapons/ric2.wav");
393                 precache_sound("weapons/ric3.wav");
394         }
395         else if (req == WR_SUICIDEMESSAGE)
396                 w_deathtypestring = "%s did the impossible";
397         else if (req == WR_KILLMESSAGE)
398         {
399                 if(w_deathtype & HITTYPE_SECONDARY)
400                         w_deathtypestring = "%s was sniped by %s";
401                 else
402                         w_deathtypestring = "%s was riddled full of holes by %s";
403         }
404         return TRUE;
405 }
406 #endif
407 #endif