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