2 REGISTER_WEAPON(UZI, w_uzi, IT_NAILS, 3, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_MID, "uzi", "uzi", _("Machine Gun"))
6 void W_UZI_SetAmmoCounter()
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
13 self.clip_load = self.uzi_load;
14 self.clip_size = autocvar_g_balance_uzi_reload_ammo; // for the crosshair ammo display
18 void W_UZI_ReloadedAndReady()
22 // now do the ammo transfer
23 self.clip_load = self.old_clip_load; // restore the ammo counter, in case we still had ammo in the weapon before reloading
24 while(self.clip_load < autocvar_g_balance_uzi_reload_ammo && self.ammo_nails) // make sure we don't add more ammo than we have
29 self.uzi_load = self.clip_load;
31 t = ATTACK_FINISHED(self) - autocvar_g_balance_uzi_reload_time - 1;
32 ATTACK_FINISHED(self) = t;
38 // return if reloading is disabled for this weapon
39 if(!autocvar_g_balance_uzi_reload_ammo)
42 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)))
47 sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
49 t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_uzi_reload_time + 1;
50 ATTACK_FINISHED(self) = t;
52 weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_uzi_reload_time, W_UZI_ReloadedAndReady);
54 self.old_clip_load = self.clip_load;
58 // leilei's fancy muzzleflash stuff
61 self.frame = self.frame + 2;
62 self.scale = self.scale * 0.5;
63 self.alpha = self.alpha - 0.25;
64 self.nextthink = time + 0.05;
68 self.think = SUB_Remove;
69 self.nextthink = time;
70 self.owner.muzzle_flash = world;
78 if (self.muzzle_flash == world)
79 self.muzzle_flash = spawn();
81 // muzzle flash for 1st person view
82 setmodel(self.muzzle_flash, "models/uziflash.md3"); // precision set below
84 self.muzzle_flash.scale = 0.75;
85 self.muzzle_flash.think = UZI_Flash_Go;
86 self.muzzle_flash.nextthink = time + 0.02;
87 self.muzzle_flash.frame = 2;
88 self.muzzle_flash.alpha = 0.75;
89 self.muzzle_flash.angles_z = random() * 180;
90 self.muzzle_flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
91 self.muzzle_flash.owner = self;
94 void W_UZI_Attack (float deathtype)
96 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 self.punchangle_x = random () - 0.5;
100 self.punchangle_y = random () - 0.5;
103 // this attack_finished just enforces a cooldown at the end of a burst
104 ATTACK_FINISHED(self) = time + autocvar_g_balance_uzi_first_refire * W_WeaponRateFactor();
106 if (self.misc_bulletcounter == 1)
107 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);
109 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);
110 endFireBallisticBullet();
112 pointparticles(particleeffectnum("uzi_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
115 W_AttachToShotorg(self.muzzle_flash, '5 0 0');
118 if (autocvar_g_casings >= 2)
119 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);
121 // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
122 if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
124 if(autocvar_g_balance_uzi_reload_ammo)
126 if (self.misc_bulletcounter == 1)
127 self.clip_load -= autocvar_g_balance_uzi_first_ammo;
129 self.clip_load -= autocvar_g_balance_uzi_sustained_ammo;
130 self.uzi_load = self.clip_load;
134 if (self.misc_bulletcounter == 1)
135 self.ammo_nails -= autocvar_g_balance_uzi_first_ammo;
137 self.ammo_nails -= autocvar_g_balance_uzi_sustained_ammo;
145 if(self.weapon != self.switchweapon) // abort immediately if switching
150 if (self.BUTTON_ATCK)
152 if (!weapon_action(self.weapon, WR_CHECKAMMO2))
154 W_SwitchWeapon_Force(self, w_getbestweapon(self));
158 self.misc_bulletcounter = self.misc_bulletcounter + 1;
159 W_UZI_Attack(WEP_UZI);
160 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, uzi_fire1_02);
163 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, w_ready);
167 void uzi_mode1_fire_auto()
171 // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
172 if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
174 if(autocvar_g_balance_uzi_reload_ammo)
176 self.clip_load -= autocvar_g_balance_uzi_sustained_ammo;
177 self.uzi_load = self.clip_load;
180 self.ammo_nails -= autocvar_g_balance_uzi_sustained_ammo;
183 if (self.BUTTON_ATCK)
184 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, uzi_mode1_fire_auto);
187 ATTACK_FINISHED(self) = time + autocvar_g_balance_uzi_first_refire * W_WeaponRateFactor();
188 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, w_ready);
192 if (!weapon_action(self.weapon, WR_CHECKAMMO1))
194 W_SwitchWeapon_Force(self, w_getbestweapon(self));
199 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 self.punchangle_x = random () - 0.5;
203 self.punchangle_y = random () - 0.5;
206 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);
207 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);
208 endFireBallisticBullet();
210 self.misc_bulletcounter = self.misc_bulletcounter + 1;
212 pointparticles(particleeffectnum("uzi_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
215 W_AttachToShotorg(self.muzzle_flash, '5 0 0');
217 if (autocvar_g_casings >= 2) // casing code
218 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 void uzi_mode1_fire_burst()
223 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 self.punchangle_x = random () - 0.5;
227 self.punchangle_y = random () - 0.5;
230 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);
231 endFireBallisticBullet();
234 pointparticles(particleeffectnum("uzi_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
237 W_AttachToShotorg(self.muzzle_flash, '5 0 0');
239 if (autocvar_g_casings >= 2) // casing code
240 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);
242 self.misc_bulletcounter = self.misc_bulletcounter + 1;
243 if (self.misc_bulletcounter == 0)
245 ATTACK_FINISHED(self) = time + autocvar_g_balance_uzi_burst_refire2 * W_WeaponRateFactor();
246 weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_uzi_burst_animtime, w_ready);
250 weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_uzi_burst_refire, uzi_mode1_fire_burst);
255 void spawnfunc_weapon_machinegun(); // defined in t_items.qc
257 float w_uzi(float req)
261 if(vlen(self.origin-self.enemy.origin) < 3000 - bound(0, skill, 10) * 200)
262 self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, FALSE);
265 self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, FALSE);
267 else if (req == WR_THINK)
269 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 else if(autocvar_g_balance_uzi_mode == 1)
273 if (self.BUTTON_ATCK)
274 if (weapon_prepareattack(0, 0))
276 self.misc_bulletcounter = 0;
277 uzi_mode1_fire_auto();
280 if(self.BUTTON_ATCK2)
281 if(weapon_prepareattack(1, 0))
283 if (!weapon_action(self.weapon, WR_CHECKAMMO2))
285 W_SwitchWeapon_Force(self, w_getbestweapon(self));
290 // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
291 if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
293 if(autocvar_g_balance_uzi_reload_ammo)
295 self.clip_load -= autocvar_g_balance_uzi_burst_ammo;
296 self.uzi_load = self.clip_load;
299 self.ammo_nails -= autocvar_g_balance_uzi_burst_ammo;
302 self.misc_bulletcounter = autocvar_g_balance_uzi_burst * -1;
303 uzi_mode1_fire_burst();
309 if (self.BUTTON_ATCK)
310 if (weapon_prepareattack(0, 0))
312 self.misc_bulletcounter = 1;
313 W_UZI_Attack(WEP_UZI); // sets attack_finished
314 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, uzi_fire1_02);
317 if (self.BUTTON_ATCK2 && autocvar_g_balance_uzi_first)
318 if (weapon_prepareattack(1, 0))
320 self.misc_bulletcounter = 1;
321 W_UZI_Attack(WEP_UZI | HITTYPE_SECONDARY); // sets attack_finished
322 weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_uzi_first_refire, w_ready);
327 if(self.switchweapon == self.weapon)
329 if(self.weaponentity.state == WS_READY)
331 self.wish_reload = 0;
337 else if (req == WR_PRECACHE)
339 precache_model ("models/uziflash.md3");
340 precache_model ("models/weapons/g_uzi.md3");
341 precache_model ("models/weapons/v_uzi.md3");
342 precache_model ("models/weapons/h_uzi.iqm");
343 precache_sound ("weapons/uzi_fire.wav");
344 precache_sound ("weapons/reload.wav");
346 else if (req == WR_SETUP)
348 weapon_setup(WEP_UZI);
349 W_UZI_SetAmmoCounter();
351 else if (req == WR_CHECKAMMO1)
353 if(autocvar_g_balance_uzi_mode == 1)
354 ammo_amount = self.ammo_nails >= autocvar_g_balance_uzi_sustained_ammo;
356 ammo_amount = self.ammo_nails >= autocvar_g_balance_uzi_first_ammo;
358 if(autocvar_g_balance_uzi_reload_ammo)
360 if(autocvar_g_balance_uzi_mode == 1)
361 ammo_amount += self.uzi_load >= autocvar_g_balance_uzi_sustained_ammo;
363 ammo_amount += self.uzi_load >= autocvar_g_balance_uzi_first_ammo;
367 else if (req == WR_CHECKAMMO2)
369 if(autocvar_g_balance_uzi_mode == 1)
370 ammo_amount = self.ammo_nails >= autocvar_g_balance_uzi_burst_ammo;
372 ammo_amount = self.ammo_nails >= autocvar_g_balance_uzi_first_ammo;
374 if(autocvar_g_balance_uzi_reload_ammo)
376 if(autocvar_g_balance_uzi_mode == 1)
377 ammo_amount += self.uzi_load >= autocvar_g_balance_uzi_burst_ammo;
379 ammo_amount += self.uzi_load >= autocvar_g_balance_uzi_first_ammo;
383 else if (req == WR_RELOAD)
391 float w_uzi(float req)
393 if(req == WR_IMPACTEFFECT)
396 org2 = w_org + w_backoff * 2;
397 pointparticles(particleeffectnum("machinegun_impact"), org2, w_backoff * 1000, 1);
400 sound(self, CHAN_PROJECTILE, "weapons/ric1.wav", VOL_BASE, ATTN_NORM);
401 else if(w_random < 0.1)
402 sound(self, CHAN_PROJECTILE, "weapons/ric2.wav", VOL_BASE, ATTN_NORM);
403 else if(w_random < 0.2)
404 sound(self, CHAN_PROJECTILE, "weapons/ric3.wav", VOL_BASE, ATTN_NORM);
406 else if(req == WR_PRECACHE)
408 precache_sound("weapons/ric1.wav");
409 precache_sound("weapons/ric2.wav");
410 precache_sound("weapons/ric3.wav");
412 else if (req == WR_SUICIDEMESSAGE)
413 w_deathtypestring = "%s did the impossible";
414 else if (req == WR_KILLMESSAGE)
416 if(w_deathtype & HITTYPE_SECONDARY)
417 w_deathtypestring = "%s was sniped by %s";
419 w_deathtypestring = "%s was riddled full of holes by %s";