]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/w_uzi.qc
Remove useless returns on attack and attack2. There are several other checks that...
[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))
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
124 // weapon frames
125 void uzi_fire1_02()
126 {
127         if(self.weapon != self.switchweapon) // abort immediately if switching
128         {
129                 w_ready();
130                 return;
131         }
132         if (self.BUTTON_ATCK)
133         {
134                 if (!weapon_action(self.weapon, WR_CHECKAMMO2))
135                 {
136                         W_SwitchWeapon_Force(self, w_getbestweapon(self));
137                         w_ready();
138                         return;
139                 }
140                 self.misc_bulletcounter = self.misc_bulletcounter + 1;
141                 W_Uzi_Attack(WEP_UZI);
142                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, uzi_fire1_02);
143         }
144         else
145                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, w_ready);
146 }
147
148
149 void uzi_mode1_fire_auto()
150 {
151         float uzi_spread;
152         
153         if (self.BUTTON_ATCK)
154                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, uzi_mode1_fire_auto);
155         else
156         {
157                 ATTACK_FINISHED(self) = time + autocvar_g_balance_uzi_first_refire * W_WeaponRateFactor();
158                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, w_ready);
159                 return;
160         }
161
162         if (!weapon_action(self.weapon, WR_CHECKAMMO1))
163         {
164                 W_SwitchWeapon_Force(self, w_getbestweapon(self));
165                 w_ready();
166                 return;
167         }
168         
169         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);
170         if (!g_norecoil)
171         {
172                 self.punchangle_x = random () - 0.5;
173                 self.punchangle_y = random () - 0.5;
174         }
175         
176         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);
177         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);
178         endFireBallisticBullet();
179         
180         self.misc_bulletcounter = self.misc_bulletcounter + 1;
181         
182         pointparticles(particleeffectnum("uzi_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
183
184         UziFlash();
185         W_AttachToShotorg(self.muzzle_flash, '5 0 0');
186         
187         if (autocvar_g_casings >= 2) // casing code
188                 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);
189
190         // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
191         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
192         {
193                 if(autocvar_g_balance_uzi_reload_ammo)
194                 {
195                         self.clip_load -= autocvar_g_balance_uzi_sustained_ammo;
196                         self.uzi_load = self.clip_load;
197                 }
198                 else
199                         self.ammo_nails -= autocvar_g_balance_uzi_sustained_ammo;
200         }
201 }
202
203 void uzi_mode1_fire_burst()
204 {
205         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);
206         if (!g_norecoil)
207         {
208                 self.punchangle_x = random () - 0.5;
209                 self.punchangle_y = random () - 0.5;
210         }
211         
212         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);
213         endFireBallisticBullet();
214         
215         
216         pointparticles(particleeffectnum("uzi_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
217
218         UziFlash();
219         W_AttachToShotorg(self.muzzle_flash, '5 0 0');
220         
221         if (autocvar_g_casings >= 2) // casing code
222                 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);
223
224         self.misc_bulletcounter = self.misc_bulletcounter + 1;
225         if (self.misc_bulletcounter == 0)
226         {
227                 ATTACK_FINISHED(self) = time + autocvar_g_balance_uzi_burst_refire2 * W_WeaponRateFactor();
228                 weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_uzi_burst_animtime, w_ready);
229         }
230         else
231         {
232                 weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_uzi_burst_refire, uzi_mode1_fire_burst);
233         }
234                 
235 }
236
237 void spawnfunc_weapon_machinegun(); // defined in t_items.qc
238
239 float w_uzi(float req)
240 {
241         if (req == WR_AIM)
242                 if(vlen(self.origin-self.enemy.origin) < 3000 - bound(0, skill, 10) * 200)
243                         self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, FALSE);
244                 else
245                 {
246                         self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, FALSE);
247                 }
248         else if (req == WR_THINK)
249         {
250                 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
251                         W_Uzi_Reload();
252                 else if(autocvar_g_balance_uzi_mode == 1)
253                 {
254                         if (self.BUTTON_ATCK)
255                         if (weapon_prepareattack(0, 0))
256                         {                               
257                                 self.misc_bulletcounter = 0;
258                                 uzi_mode1_fire_auto();
259                         }
260                         
261                         if(self.BUTTON_ATCK2)
262                         if(weapon_prepareattack(1, 0))
263                         {
264                                 if (!weapon_action(self.weapon, WR_CHECKAMMO2))
265                                 {
266                                         W_SwitchWeapon_Force(self, w_getbestweapon(self));
267                                         w_ready();
268                                         return FALSE;
269                                 }
270
271                                 // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
272                                 if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
273                                 {
274                                         if(autocvar_g_balance_uzi_reload_ammo)
275                                         {
276                                                 self.clip_load -= autocvar_g_balance_uzi_burst_ammo;
277                                                 self.uzi_load = self.clip_load;
278                                         }
279                                         else
280                                                 self.ammo_nails -= autocvar_g_balance_uzi_burst_ammo;
281                                 }
282
283                                 self.misc_bulletcounter = autocvar_g_balance_uzi_burst * -1;
284                                 uzi_mode1_fire_burst();
285                         }
286                 }
287                 else
288                 {
289                         
290                         if (self.BUTTON_ATCK)
291                         if (weapon_prepareattack(0, 0))
292                         {
293                                 self.misc_bulletcounter = 1;
294                                 W_Uzi_Attack(WEP_UZI); // sets attack_finished
295                                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, uzi_fire1_02);
296                         }
297
298                         if (self.BUTTON_ATCK2 && autocvar_g_balance_uzi_first)
299                         if (weapon_prepareattack(1, 0))
300                         {
301                                 self.misc_bulletcounter = 1;
302                                 W_Uzi_Attack(WEP_UZI | HITTYPE_SECONDARY); // sets attack_finished
303                                 weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_uzi_first_refire, w_ready);
304                         }
305                 }
306         if(self.wish_reload)
307         {
308             if(self.switchweapon == self.weapon)
309             {
310                 if(self.weaponentity.state == WS_READY)
311                 {
312                     self.wish_reload = 0;
313                     W_Uzi_Reload();
314                 }
315             }
316         }
317         }
318         else if (req == WR_PRECACHE)
319         {
320                 precache_model ("models/uziflash.md3");
321                 precache_model ("models/weapons/g_uzi.md3");
322                 precache_model ("models/weapons/v_uzi.md3");
323                 precache_model ("models/weapons/h_uzi.iqm");
324                 precache_sound ("weapons/uzi_fire.wav");
325         }
326         else if (req == WR_SETUP)
327         {
328                 weapon_setup(WEP_UZI);
329                 W_Uzi_SetAmmoCounter();
330         }
331         else if (req == WR_CHECKAMMO1)
332         {
333                 if(autocvar_g_balance_uzi_mode == 1)
334                         return self.ammo_nails >= autocvar_g_balance_uzi_sustained_ammo;
335                 else
336                         return self.ammo_nails >= autocvar_g_balance_uzi_first_ammo;
337         }
338         else if (req == WR_CHECKAMMO2)
339         {
340                 if(autocvar_g_balance_uzi_mode == 1)
341                         return self.ammo_nails >= autocvar_g_balance_uzi_burst_ammo;
342                 else
343                         return self.ammo_nails >= autocvar_g_balance_uzi_first_ammo;
344         }
345         else if (req == WR_RELOAD)
346         {
347                 W_Uzi_Reload();
348         }
349         return TRUE;
350 };
351 #endif
352 #ifdef CSQC
353 float w_uzi(float req)
354 {
355         if(req == WR_IMPACTEFFECT)
356         {
357                 vector org2;
358                 org2 = w_org + w_backoff * 2;
359                 pointparticles(particleeffectnum("machinegun_impact"), org2, w_backoff * 1000, 1);
360                 if(!w_issilent)
361                         if(w_random < 0.05)
362                                 sound(self, CHAN_PROJECTILE, "weapons/ric1.wav", VOL_BASE, ATTN_NORM);
363                         else if(w_random < 0.1)
364                                 sound(self, CHAN_PROJECTILE, "weapons/ric2.wav", VOL_BASE, ATTN_NORM);
365                         else if(w_random < 0.2)
366                                 sound(self, CHAN_PROJECTILE, "weapons/ric3.wav", VOL_BASE, ATTN_NORM);
367         }
368         else if(req == WR_PRECACHE)
369         {
370                 precache_sound("weapons/ric1.wav");
371                 precache_sound("weapons/ric2.wav");
372                 precache_sound("weapons/ric3.wav");
373         }
374         else if (req == WR_SUICIDEMESSAGE)
375                 w_deathtypestring = "%s did the impossible";
376         else if (req == WR_KILLMESSAGE)
377         {
378                 if(w_deathtype & HITTYPE_SECONDARY)
379                         w_deathtypestring = "%s was sniped by %s";
380                 else
381                         w_deathtypestring = "%s was riddled full of holes by %s";
382         }
383         return TRUE;
384 }
385 #endif
386 #endif