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);
326 else if (req == WR_PRECACHE)
328 precache_model ("models/uziflash.md3");
329 precache_model ("models/weapons/g_uzi.md3");
330 precache_model ("models/weapons/v_uzi.md3");
331 precache_model ("models/weapons/h_uzi.iqm");
332 precache_sound ("weapons/uzi_fire.wav");
333 precache_sound ("weapons/reload.wav");
335 else if (req == WR_SETUP)
337 weapon_setup(WEP_UZI);
338 W_UZI_SetAmmoCounter();
340 else if (req == WR_CHECKAMMO1)
342 if(autocvar_g_balance_uzi_mode == 1)
343 ammo_amount = self.ammo_nails >= autocvar_g_balance_uzi_sustained_ammo;
345 ammo_amount = self.ammo_nails >= autocvar_g_balance_uzi_first_ammo;
347 if(autocvar_g_balance_uzi_reload_ammo)
349 if(autocvar_g_balance_uzi_mode == 1)
350 ammo_amount += self.uzi_load >= autocvar_g_balance_uzi_sustained_ammo;
352 ammo_amount += self.uzi_load >= autocvar_g_balance_uzi_first_ammo;
356 else if (req == WR_CHECKAMMO2)
358 if(autocvar_g_balance_uzi_mode == 1)
359 ammo_amount = self.ammo_nails >= autocvar_g_balance_uzi_burst_ammo;
361 ammo_amount = self.ammo_nails >= autocvar_g_balance_uzi_first_ammo;
363 if(autocvar_g_balance_uzi_reload_ammo)
365 if(autocvar_g_balance_uzi_mode == 1)
366 ammo_amount += self.uzi_load >= autocvar_g_balance_uzi_burst_ammo;
368 ammo_amount += self.uzi_load >= autocvar_g_balance_uzi_first_ammo;
372 else if (req == WR_RESETPLAYER)
374 // all weapons must be fully loaded when we spawn
375 self.uzi_load = autocvar_g_balance_uzi_reload_ammo;
377 else if (req == WR_RELOAD)
385 float w_uzi(float req)
387 if(req == WR_IMPACTEFFECT)
390 org2 = w_org + w_backoff * 2;
391 pointparticles(particleeffectnum("machinegun_impact"), org2, w_backoff * 1000, 1);
394 sound(self, CHAN_PROJECTILE, "weapons/ric1.wav", VOL_BASE, ATTN_NORM);
395 else if(w_random < 0.1)
396 sound(self, CHAN_PROJECTILE, "weapons/ric2.wav", VOL_BASE, ATTN_NORM);
397 else if(w_random < 0.2)
398 sound(self, CHAN_PROJECTILE, "weapons/ric3.wav", VOL_BASE, ATTN_NORM);
400 else if(req == WR_PRECACHE)
402 precache_sound("weapons/ric1.wav");
403 precache_sound("weapons/ric2.wav");
404 precache_sound("weapons/ric3.wav");
406 else if (req == WR_SUICIDEMESSAGE)
407 w_deathtypestring = "%s did the impossible";
408 else if (req == WR_KILLMESSAGE)
410 if(w_deathtype & HITTYPE_SECONDARY)
411 w_deathtypestring = "%s was sniped by %s";
413 w_deathtypestring = "%s was riddled full of holes by %s";