Merge remote branch 'refs/remotes/origin/fruitiex/racefixes'
[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 .entity muzzle_flash;
6
7 // leilei's fancy muzzleflash stuff
8 void Uzi_Flash_Go() 
9 {       
10         self.frame = self.frame + 2;
11         self.scale = self.scale * 0.5;
12         self.alpha = self.alpha - 0.25;
13         self.nextthink = time + 0.05;
14
15         if (self.alpha <= 0)
16         {
17                 self.think = SUB_Remove;
18                 self.nextthink = time;
19                 self.owner.muzzle_flash = world;
20                 return;
21         }
22         
23 }
24
25 void UziFlash()
26 {       
27         if (self.muzzle_flash == world)
28                 self.muzzle_flash = spawn();    
29         
30         // muzzle flash for 1st person view
31         setmodel(self.muzzle_flash, "models/uziflash.md3"); // precision set below
32         
33         self.muzzle_flash.scale = 0.75;
34         self.muzzle_flash.think = Uzi_Flash_Go;
35         self.muzzle_flash.nextthink = time + 0.02;
36         self.muzzle_flash.frame = 2;
37         self.muzzle_flash.alpha = 0.75;
38         self.muzzle_flash.angles_z = random() * 180;
39         self.muzzle_flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
40         self.muzzle_flash.owner = self;
41         
42         
43 }
44
45 .float uzi_bulletcounter;
46 void W_Uzi_Attack (float deathtype)
47 {
48         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
49         {
50                 if (self.uzi_bulletcounter == 1)
51                         self.ammo_nails = self.ammo_nails - cvar("g_balance_uzi_first_ammo");
52                 else
53                         self.ammo_nails = self.ammo_nails - cvar("g_balance_uzi_sustained_ammo");
54         }
55         W_SetupShot (self, cvar("g_antilag_bullets") && cvar("g_balance_uzi_speed") >= cvar("g_antilag_bullets"), 0, "weapons/uzi_fire.wav", cvar("g_balance_uzi_first_damage"));
56         if (!g_norecoil)
57         {
58                 self.punchangle_x = random () - 0.5;
59                 self.punchangle_y = random () - 0.5;
60         }
61
62         // this attack_finished just enforces a cooldown at the end of a burst
63         ATTACK_FINISHED(self) = time + cvar("g_balance_uzi_first_refire") * W_WeaponRateFactor();
64
65         if (self.uzi_bulletcounter == 1)
66                 fireBallisticBullet(w_shotorg, w_shotdir, cvar("g_balance_uzi_first_spread"), cvar("g_balance_uzi_speed"), 5, cvar("g_balance_uzi_first_damage"), 0, cvar("g_balance_uzi_first_force"), deathtype, 0, 1, cvar("g_balance_uzi_bulletconstant"));
67         else
68                 fireBallisticBullet(w_shotorg, w_shotdir, cvar("g_balance_uzi_sustained_spread"), cvar("g_balance_uzi_speed"), 5, cvar("g_balance_uzi_sustained_damage"), 0, cvar("g_balance_uzi_sustained_force"), deathtype, 0, 1, cvar("g_balance_uzi_bulletconstant"));
69         endFireBallisticBullet();
70
71         pointparticles(particleeffectnum("uzi_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
72
73         UziFlash();
74         W_AttachToShotorg(self.muzzle_flash, '5 0 0');
75
76         // casing code
77         if (cvar("g_casings") >= 2)
78                 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);
79 }
80
81 // weapon frames
82 void uzi_fire1_02()
83 {
84         if(self.weapon != self.switchweapon) // abort immediately if switching
85         {
86                 w_ready();
87                 return;
88         }
89         if (self.BUTTON_ATCK)
90         {
91                 if (!weapon_action(self.weapon, WR_CHECKAMMO2))
92                 {
93                         W_SwitchWeapon_Force(self, w_getbestweapon(self));
94                         w_ready();
95                         return;
96                 }
97                 self.uzi_bulletcounter = self.uzi_bulletcounter + 1;
98                 W_Uzi_Attack(WEP_UZI);
99                 weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_uzi_sustained_refire"), uzi_fire1_02);
100         }
101         else
102                 weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_uzi_sustained_refire"), w_ready);
103 };
104
105 void spawnfunc_weapon_machinegun(); // defined in t_items.qc
106
107 float w_uzi(float req)
108 {
109         if (req == WR_AIM)
110                 if(vlen(self.origin-self.enemy.origin) < 3000 - bound(0, skill, 10) * 200)
111                         self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, FALSE);
112                 else
113                 {
114                         self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, FALSE);
115                 }
116         else if (req == WR_THINK)
117         {
118                 if (self.BUTTON_ATCK)
119                 if (weapon_prepareattack(0, 0))
120                 {
121                         self.uzi_bulletcounter = 1;
122                         W_Uzi_Attack(WEP_UZI); // sets attack_finished
123                         weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_uzi_sustained_refire"), uzi_fire1_02);
124                 }
125                 if (self.BUTTON_ATCK2 && cvar("g_balance_uzi_first"))
126                 if (weapon_prepareattack(1, 0))
127                 {
128                         self.uzi_bulletcounter = 1;
129                         W_Uzi_Attack(WEP_UZI | HITTYPE_SECONDARY); // sets attack_finished
130                         weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_uzi_first_refire"), w_ready);
131                 }
132         }
133         else if (req == WR_PRECACHE)
134         {
135                 precache_model ("models/uziflash.md3");
136                 precache_model ("models/weapons/g_uzi.md3");
137                 precache_model ("models/weapons/v_uzi.md3");
138                 precache_model ("models/weapons/h_uzi.iqm");
139                 precache_sound ("weapons/uzi_fire.wav");
140         }
141         else if (req == WR_SETUP)
142                 weapon_setup(WEP_UZI);
143         else if (req == WR_CHECKAMMO1)
144                 return self.ammo_nails >= cvar("g_balance_uzi_first_ammo");
145         else if (req == WR_CHECKAMMO2)
146                 return self.ammo_nails >= cvar("g_balance_uzi_first_ammo");
147         return TRUE;
148 };
149 #endif
150 #ifdef CSQC
151 float w_uzi(float req)
152 {
153         if(req == WR_IMPACTEFFECT)
154         {
155                 vector org2;
156                 org2 = w_org + w_backoff * 2;
157                 pointparticles(particleeffectnum("machinegun_impact"), org2, w_backoff * 1000, 1);
158                 if(!w_issilent)
159                         if(w_random < 0.05)
160                                 sound(self, CHAN_PROJECTILE, "weapons/ric1.wav", VOL_BASE, ATTN_NORM);
161                         else if(w_random < 0.1)
162                                 sound(self, CHAN_PROJECTILE, "weapons/ric2.wav", VOL_BASE, ATTN_NORM);
163                         else if(w_random < 0.2)
164                                 sound(self, CHAN_PROJECTILE, "weapons/ric3.wav", VOL_BASE, ATTN_NORM);
165         }
166         else if(req == WR_PRECACHE)
167         {
168                 precache_sound("weapons/ric1.wav");
169                 precache_sound("weapons/ric2.wav");
170                 precache_sound("weapons/ric3.wav");
171         }
172         else if (req == WR_SUICIDEMESSAGE)
173                 w_deathtypestring = "%s did the impossible";
174         else if (req == WR_KILLMESSAGE)
175         {
176                 if(w_deathtype & HITTYPE_SECONDARY)
177                         w_deathtypestring = "%s was sniped by %s";
178                 else
179                         w_deathtypestring = "%s was riddled full of holes by %s";
180         }
181         return TRUE;
182 }
183 #endif
184 #endif