]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/w_rcalpistol.qc
f91538acc36b1dc54b22ac0fd47f64a91561007e
[divverent/nexuiz.git] / data / qcsrc / server / w_rcalpistol.qc
1 #ifdef REGISTER_WEAPON
2 REGISTER_WEAPON(RCALPISTOL, w_rcalpistol, IT_NAILS, 2, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_LOW, "rcalpistol", "rcalpistol", "Rifle Caliber Pistol");
3 #else
4 //Rifle Caliber Pistol Primary mode: semi automatic fire, Secondary: Toggle laser pointer (about .75 of an inch below the barrel)**
5 //Uses the same type of rifle ammo as the rifle, should be the same amount (RCALPISTOL uses 10 of the bullet ammo, this probably should too)
6 //This does not fire "regular" pistol bullets like a regular pistol or submachine gun shoots. If you'd like a pistol like that please make a new one :)
7
8 .float rcalpistol_release;
9 .float rcalpistol_accumulator;
10 .float rcalpistol_bulletcounter; //Added because even though this is in defs.qc, that doesn't seem to matter;
11
12 float W_RCalPistol_CheckMaxBullets(float checkammo)
13 {
14         float maxbulls;
15         maxbulls = cvar("g_balance_rcalpistol_magazinecapacity");
16         if(!maxbulls)
17                 maxbulls = 6; // Small magazine
18         if(checkammo)
19                 if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
20                         maxbulls = min(maxbulls, floor(self.ammo_nails / min(cvar("g_balance_rcalpistol_primary_ammo"), cvar("g_balance_rcalpistol_secondary_ammo"))));
21         if(self.rcalpistol_bulletcounter > maxbulls || !cvar("g_balance_rcalpistol_magazinecapacity"))
22                 self.rcalpistol_bulletcounter = maxbulls;
23         return (self.rcalpistol_bulletcounter == maxbulls);
24 }
25
26 void W_RCalPistol_ReloadedAndReady()
27 {
28         float t;
29         self.rcalpistol_bulletcounter = cvar("g_balance_rcalpistol_magazinecapacity");
30         W_RCalPistol_CheckMaxBullets(TRUE);
31         t = ATTACK_FINISHED(self) - cvar("g_balance_rcalpistol_reloadtime") - 1;
32         ATTACK_FINISHED(self) = t;
33         w_ready();
34 }
35
36 void W_RCalPistol_Reload()
37 {
38         float t;
39
40         W_RCalPistol_CheckMaxBullets(TRUE);
41         if (self.rcalpistol_bulletcounter >= cvar("g_balance_rcalpistol_magazinecapacity"))
42                 return;
43
44         if(self.ammo_nails < min(cvar("g_balance_rcalpistol_primary_ammo"), cvar("g_balance_rcalpistol_secondary_ammo")))
45         {
46                 self.rcalpistol_bulletcounter = -1; // reload later
47                 return;
48         }
49         
50         if (self.weaponentity)
51         {
52                 if (self.weaponentity.wframe == WFRAME_RELOAD)
53                         return;
54
55                 // allow to switch away while reloading, but this will cause a new reload!
56                 self.weaponentity.state = WS_READY;
57         }
58
59         sound (self, CHAN_WEAPON2, "weapons/rcalpistol_reload.wav", VOL_BASE, ATTN_NORM);
60
61         t = max(time, ATTACK_FINISHED(self)) + cvar("g_balance_rcalpistol_reloadtime") + 1;
62         ATTACK_FINISHED(self) = t;
63
64         weapon_thinkf(WFRAME_RELOAD, cvar("g_balance_rcalpistol_reloadtime"), W_RCalPistol_ReloadedAndReady);
65
66         self.rcalpistol_bulletcounter = -1;
67 }
68
69 void W_RCalPistol_CheckReloadAndReady()
70 {
71         w_ready();
72         if (self.rcalpistol_bulletcounter <= 0)
73                 W_RCalPistol_Reload();
74         else
75                 w_ready();
76 }
77
78 void W_RCalPistol_FireBullet(float pSpread, float pDamage, float pHeadshotAddedDamage, float pForce, float pSpeed, float pLifetime, float pAmmo, float deathtype, float pBulletConstant)
79 {
80         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
81                 self.ammo_nails -= pAmmo;
82
83         if(deathtype & HITTYPE_SECONDARY)
84                 W_SetupShot (self, cvar("g_antilag_bullets") && pSpeed >= cvar("g_antilag_bullets"), 2, "weapons/rcalpistol_fire2.wav", cvar("g_balance_rcalpistol_secondary_damage"));
85         else
86                 W_SetupShot (self, cvar("g_antilag_bullets") && pSpeed >= cvar("g_antilag_bullets"), 2, "weapons/rcalpistol_fire.wav", cvar("g_balance_rcalpistol_primary_damage"));
87
88         pointparticles(particleeffectnum("shotgun_muzzleflash"), w_shotorg, w_shotdir * 2000, 1);
89
90         if(self.BUTTON_ZOOM) // if zoomed, shoot from the eye
91         {
92                 w_shotdir = v_forward;
93                 w_shotorg = self.origin + self.view_ofs + ((w_shotorg - self.origin - self.view_ofs) * v_forward) * v_forward;
94         }
95
96         fireBallisticBullet(w_shotorg, w_shotdir, pSpread, pSpeed, pLifetime, pDamage, pHeadshotAddedDamage / pDamage, pForce, deathtype, (cvar("g_balance_rcalpistol_tracer") ? EF_RED : EF_BLUE), 1, pBulletConstant);
97         endFireBallisticBullet();
98
99         if (cvar("g_casings") >= 2)
100                 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);
101         
102         self.rcalpistol_bulletcounter = self.rcalpistol_bulletcounter - 1;
103         W_RCalPistol_CheckMaxBullets(TRUE);
104 }
105
106 void W_RCalPistol_Attack()
107 {
108         W_RCalPistol_FireBullet(cvar("g_balance_rcalpistol_primary_spread"), cvar("g_balance_rcalpistol_primary_damage"), cvar("g_balance_rcalpistol_primary_headshotaddeddamage"), cvar("g_balance_rcalpistol_primary_force"), cvar("g_balance_rcalpistol_primary_speed"), cvar("g_balance_rcalpistol_primary_lifetime"), cvar("g_balance_rcalpistol_primary_ammo"), WEP_RCALPISTOL, cvar("g_balance_rcalpistol_primary_bulletconstant"));
109 }
110
111 void W_RCalPistol_Attack2()
112 {
113         W_RCalPistol_FireBullet(cvar("g_balance_rcalpistol_secondary_spread"), cvar("g_balance_rcalpistol_secondary_damage"), cvar("g_balance_rcalpistol_secondary_headshotaddeddamage"), cvar("g_balance_rcalpistol_secondary_force"), cvar("g_balance_rcalpistol_secondary_speed"), cvar("g_balance_rcalpistol_secondary_lifetime"), cvar("g_balance_rcalpistol_secondary_ammo"), WEP_RCALPISTOL | HITTYPE_SECONDARY, cvar("g_balance_rcalpistol_secondary_bulletconstant"));
114 }
115
116 void spawnfunc_weapon_rcalpistol (void)
117 {
118         weapon_defaultspawnfunc(WEP_RCALPISTOL);
119 }
120
121 .float bot_secondary_rcalpistolmooth;
122 float w_rcalpistol(float req)
123 {
124         float full;
125         if (req == WR_AIM)
126         {
127                 self.BUTTON_ATCK=FALSE;
128                 self.BUTTON_ATCK2=FALSE;
129                 if(vlen(self.origin-self.enemy.origin) > 1000)
130                         self.bot_secondary_rcalpistolmooth = 0;
131                 if(self.bot_secondary_rcalpistolmooth == 0)
132                 {
133                         if(bot_aim(cvar("g_balance_rcalpistol_primary_speed"), 0, cvar("g_balance_rcalpistol_primary_lifetime"), TRUE))
134                         {
135                                 self.BUTTON_ATCK = TRUE;
136                                 if(random() < 0.01) self.bot_secondary_rcalpistolmooth = 1;
137                         }
138                 }
139                 else
140                 {
141                         if(bot_aim(cvar("g_balance_rcalpistol_secondary_speed"), 0, cvar("g_balance_rcalpistol_secondary_lifetime"), TRUE))
142                         {
143                                 self.BUTTON_ATCK2 = TRUE;
144                                 if(random() < 0.03) self.bot_secondary_rcalpistolmooth = 0;
145                         }
146                 }
147         }
148         else if (req == WR_THINK)
149         {
150                 if(self.rcalpistol_bulletcounter < 0) // forced reload (e.g. because interrupted)
151                 {
152                         if(self.switchweapon == self.weapon)
153                         if(self.weaponentity.state == WS_READY)
154                                 W_RCalPistol_Reload();
155                 }
156                 else
157                 {
158                         self.rcalpistol_accumulator = bound(time - cvar("g_balance_rcalpistol_bursttime"), self.rcalpistol_accumulator, time);
159                         if(self.rcalpistol_release)
160                         {
161                                 if (self.BUTTON_ATCK)
162                                 if (time >= self.rcalpistol_accumulator + cvar("g_balance_rcalpistol_primary_burstcost"))
163                                 if (weapon_prepareattack(0, cvar("g_balance_rcalpistol_primary_refire")))
164                                 {
165                                         W_RCalPistol_Attack();
166                                         weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_rcalpistol_primary_animtime"), W_RCalPistol_CheckReloadAndReady);
167                                         self.rcalpistol_accumulator += cvar("g_balance_rcalpistol_primary_burstcost");
168                                         self.rcalpistol_release = 0;
169                                 }
170                                 if (self.BUTTON_ATCK2)
171                                 if (time >= self.rcalpistol_accumulator + cvar("g_balance_rcalpistol_secondary_burstcost"))
172                                 if (weapon_prepareattack(1, cvar("g_balance_rcalpistol_secondary_refire")))
173                                 {
174                                         W_RCalPistol_Attack2();
175                                         weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_rcalpistol_secondary_animtime"), W_RCalPistol_CheckReloadAndReady);
176                                         self.rcalpistol_accumulator += cvar("g_balance_rcalpistol_secondary_burstcost");
177                                         self.rcalpistol_release = 0;
178                                 }
179                         }
180                         if not(self.BUTTON_ATCK || self.BUTTON_ATCK2)
181                                 self.rcalpistol_release = 1;
182                 }
183         }
184         else if (req == WR_PRECACHE)
185         {               
186                 precache_model ("models/weapons/g_rcalpistol.md3");
187                 precache_model ("models/weapons/v_rcalpistol.md3");
188                 precache_model ("models/weapons/h_rcalpistol.dpm");
189                 precache_sound ("weapons/campingrifle_reload.wav");
190                 precache_sound ("weapons/campingrifle_fire.wav");
191                 precache_sound ("weapons/campingrifle_fire2.wav");
192         }
193         else if (req == WR_SETUP)
194         {
195                 weapon_setup(WEP_RCALPISTOL);
196
197                 full = W_RCalPistol_CheckMaxBullets(TRUE);
198                 if(cvar("g_balance_rcalpistol_auto_reload_after_changing_weapons"))
199                         if(!full)
200                                 self.rcalpistol_bulletcounter = -1;
201         }
202         else if (req == WR_CHECKAMMO1)
203                 return self.ammo_nails >= cvar("g_balance_rcalpistol_primary_ammo");
204         else if (req == WR_CHECKAMMO2)
205                 return self.ammo_nails >= cvar("g_balance_rcalpistol_secondary_ammo");
206         else if (req == WR_SUICIDEMESSAGE)
207         {
208                 if(w_deathtype & HITTYPE_SECONDARY)
209                         w_deathtypestring = "shot themself automatically";
210                 else
211                         w_deathtypestring = "sniped themself somehow";
212         }
213         else if (req == WR_KILLMESSAGE)
214         {
215                 if(w_deathtype & HITTYPE_SECONDARY)
216                 {
217                         if(w_deathtype & HITTYPE_BOUNCE)
218                                 w_deathtypestring = "failed to hide from #'s bullet hail";
219                         else
220                                 w_deathtypestring = "died in #'s bullet hail";
221                 }
222                 else
223                 {
224                         if(w_deathtype & HITTYPE_BOUNCE)
225                         {
226                                 // TODO special headshot message here too?
227                                 w_deathtypestring = "failed to hide from #'s pistol";
228                         }
229                         else
230                         {
231                                 if(w_deathtype & HITTYPE_HEADSHOT)
232                                         w_deathtypestring = "was executed by #";
233                                 else
234                                         w_deathtypestring = "was shot down by #";
235                         }
236                 }
237         }
238         else if (req == WR_RELOAD)
239         {
240                 W_RCalPistol_Reload();
241         }
242         else if (req == WR_RESETPLAYER)
243         {
244                 self.rcalpistol_accumulator = time - cvar("g_balance_rcalpistol_bursttime");
245                 self.rcalpistol_bulletcounter = cvar("g_balance_rcalpistol_magazinecapacity");
246                 W_RCalPistol_CheckMaxBullets(FALSE);
247         }
248         return TRUE;
249 };
250 #endif