]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/w_campingrifle.qc
rifle bullet counter indicator
[divverent/nexuiz.git] / data / qcsrc / server / w_campingrifle.qc
1 //Camping rifle Primary mode: manually operated bolt*, Secondary: full automatic**
2 //* Manually operating the bolt means that all the power of the gas is used to propell the bullet. In this mode the bolt is prevented from moving backwards in response to the firing of the bullet.
3 //** In fully automatic mode some of the gas is used to extract and reload the next cartrige, thus there is less power and range.
4
5 void W_Campingrifle_ReloadedAndReady()
6 {
7         float t;
8         self.campingrifle_bulletcounter = cvar("g_balance_campingrifle_magazinecapacity");
9         t = ATTACK_FINISHED(self) - cvar("g_balance_campingrifle_reloadtime") - 1;
10         ATTACK_FINISHED(self) = t;
11         w_ready();
12 }
13
14 void W_Campingrifle_Reload()
15 {
16         float t;
17
18         if (self.campingrifle_bulletcounter >= cvar("g_balance_campingrifle_magazinecapacity"))
19                 return;
20         
21         if (self.weaponentity)
22         {
23                 if (self.weaponentity.wframe == WFRAME_RELOAD)
24                         return;
25
26                 // allow to switch away while reloading, but this will cause a new reload!
27                 self.weaponentity.state = WS_READY;
28         }
29
30         sound (self, CHAN_WEAPON2, "weapons/campingrifle_reload.wav", VOL_BASE, ATTN_NORM);
31
32         t = max(time, ATTACK_FINISHED(self)) + cvar("g_balance_campingrifle_reloadtime") + 1;
33         ATTACK_FINISHED(self) = t;
34
35         weapon_thinkf(WFRAME_RELOAD, cvar("g_balance_campingrifle_reloadtime"), W_Campingrifle_ReloadedAndReady);
36
37         self.campingrifle_bulletcounter = -1;
38 }
39
40 void W_Campingrifle_CheckReloadAndReady()
41 {
42         w_ready();
43         if (self.campingrifle_bulletcounter <= 0)
44                 W_Campingrifle_Reload();
45         else
46                 w_ready();
47 }
48
49 void W_CampingRifle_FireBullet(float pSpread, float pDamage, float pHeadshotAddedDamage, float pForce, float pSpeed, float pLifetime, float pAmmo, float deathtype, float pBulletConstant)
50 {
51         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
52                 self.ammo_nails -= pAmmo;
53
54         if(deathtype & HITTYPE_SECONDARY)
55                 W_SetupShot (self, cvar("g_antilag_bullets") && pSpeed >= cvar("g_antilag_bullets"), 2, "weapons/campingrifle_fire2.wav", cvar("g_balance_campingrifle_secondary_damage"));
56         else
57                 W_SetupShot (self, cvar("g_antilag_bullets") && pSpeed >= cvar("g_antilag_bullets"), 2, "weapons/campingrifle_fire.wav", cvar("g_balance_campingrifle_primary_damage"));
58
59         pointparticles(particleeffectnum("shotgun_muzzleflash"), w_shotorg, w_shotdir * 2000, 1);
60
61         if(self.BUTTON_ZOOM) // if zoomed, shoot from the eye
62         {
63                 w_shotdir = v_forward;
64                 w_shotorg = self.origin + self.view_ofs + ((w_shotorg - self.origin - self.view_ofs) * v_forward) * v_forward;
65         }
66
67         fireBallisticBullet(w_shotorg, w_shotdir, pSpread, pSpeed, pLifetime, pDamage, pHeadshotAddedDamage / pDamage, pForce, deathtype, EF_RED, 1, pBulletConstant);
68
69         if (cvar("g_casings") >= 2)
70                 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);
71         
72         self.campingrifle_bulletcounter = self.campingrifle_bulletcounter - 1;
73 }
74
75 void W_Campingrifle_Attack()
76 {
77         W_CampingRifle_FireBullet(cvar("g_balance_campingrifle_primary_spread"), cvar("g_balance_campingrifle_primary_damage"), cvar("g_balance_campingrifle_primary_headshotaddeddamage"), cvar("g_balance_campingrifle_primary_force"), cvar("g_balance_campingrifle_primary_speed"), cvar("g_balance_campingrifle_primary_lifetime"), cvar("g_balance_campingrifle_primary_ammo"), WEP_CAMPINGRIFLE, cvar("g_balance_campingrifle_primary_bulletconstant"));
78 }
79
80 void W_Campingrifle_Attack2()
81 {
82         W_CampingRifle_FireBullet(cvar("g_balance_campingrifle_secondary_spread"), cvar("g_balance_campingrifle_secondary_damage"), cvar("g_balance_campingrifle_secondary_headshotaddeddamage"), cvar("g_balance_campingrifle_secondary_force"), cvar("g_balance_campingrifle_secondary_speed"), cvar("g_balance_campingrifle_secondary_lifetime"), cvar("g_balance_campingrifle_secondary_ammo"), WEP_CAMPINGRIFLE | HITTYPE_SECONDARY, cvar("g_balance_campingrifle_secondary_bulletconstant"));
83 }
84
85 void spawnfunc_weapon_campingrifle (void)
86 {
87         weapon_defaultspawnfunc(WEP_CAMPINGRIFLE);
88 }
89
90 .float bot_secondary_campingriflemooth;
91 float w_campingrifle(float req)
92 {
93         if (req == WR_AIM)
94         {
95                 self.BUTTON_ATCK=FALSE;
96                 self.BUTTON_ATCK2=FALSE;
97                 if(vlen(self.origin-self.enemy.origin) > 1000)
98                         self.bot_secondary_campingriflemooth = 0;
99                 if(self.bot_secondary_campingriflemooth == 0)
100                 {
101                         if(bot_aim(cvar("g_balance_campingrifle_primary_speed"), 0, cvar("g_balance_campingrifle_primary_lifetime"), TRUE))
102                         {
103                                 self.BUTTON_ATCK = TRUE;
104                                 if(random() < 0.01) self.bot_secondary_campingriflemooth = 1;
105                         }
106                 }
107                 else
108                 {
109                         if(bot_aim(cvar("g_balance_campingrifle_secondary_speed"), 0, cvar("g_balance_campingrifle_secondary_lifetime"), TRUE))
110                         {
111                                 self.BUTTON_ATCK2 = TRUE;
112                                 if(random() < 0.03) self.bot_secondary_campingriflemooth = 0;
113                         }
114                 }
115         }
116         else if (req == WR_THINK)
117         {
118                 if(self.campingrifle_bulletcounter < 0) // forced reload (e.g. because interrupted)
119                 {
120                         if(self.switchweapon == self.weapon)
121                         if(self.weaponentity.state == WS_READY)
122                                 W_Campingrifle_Reload();
123                 }
124                 else
125                 {
126                         if (self.BUTTON_ATCK)
127                         if (weapon_prepareattack(0, cvar("g_balance_campingrifle_primary_refire")))
128                         {
129                                 W_Campingrifle_Attack();
130                                 weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_campingrifle_primary_animtime"), W_Campingrifle_CheckReloadAndReady);
131                         }
132                         if (self.BUTTON_ATCK2)
133                         if (weapon_prepareattack(1, cvar("g_balance_campingrifle_secondary_refire")))
134                         {
135                                 W_Campingrifle_Attack2();
136                                 weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_campingrifle_secondary_animtime"), W_Campingrifle_CheckReloadAndReady);
137                         }
138                 }
139         }
140         else if (req == WR_PRECACHE)
141         {               
142                 precache_model ("models/weapons/g_campingrifle.md3");
143                 precache_model ("models/weapons/v_campingrifle.md3");
144                 precache_model ("models/weapons/h_campingrifle.dpm");
145                 precache_sound ("weapons/campingrifle_reload.wav");
146                 precache_sound ("weapons/campingrifle_fire.wav");
147                 precache_sound ("weapons/campingrifle_fire2.wav");
148         }
149         else if (req == WR_SETUP)
150         {
151                 weapon_setup(WEP_CAMPINGRIFLE);
152
153                 if(cvar("g_balance_campingrifle_auto_reload_after_changing_weapons"))
154                 {
155                         if(self.campingrifle_bulletcounter < cvar("g_balance_campingrifle_magazinecapacity"))
156                                 self.campingrifle_bulletcounter = -1;
157                 }
158         }
159         else if (req == WR_CHECKAMMO1)
160                 return self.ammo_nails >= cvar("g_balance_campingrifle_primary_ammo");
161         else if (req == WR_CHECKAMMO2)
162                 return self.ammo_nails >= cvar("g_balance_campingrifle_secondary_ammo");
163         else if (req == WR_SUICIDEMESSAGE)
164         {
165                 if(w_deathtype & HITTYPE_SECONDARY)
166                         w_deathtypestring = "shot himself automatically";
167                 else
168                         w_deathtypestring = "sniped himself somehow";
169         }
170         else if (req == WR_KILLMESSAGE)
171         {
172                 if(w_deathtype & HITTYPE_SECONDARY)
173                 {
174                         if(w_deathtype & HITTYPE_BOUNCE)
175                                 w_deathtypestring = "failed to hide from #'s bullet hail";
176                         else
177                                 w_deathtypestring = "died in #'s bullet hail";
178                 }
179                 else
180                 {
181                         if(w_deathtype & HITTYPE_BOUNCE)
182                         {
183                                 // TODO special headshot message here too?
184                                 w_deathtypestring = "failed to hide from #'s rifle";
185                         }
186                         else
187                         {
188                                 if(w_deathtype & HITTYPE_HEADSHOT)
189                                         w_deathtypestring = "got hit in the head by #";
190                                 else
191                                         w_deathtypestring = "was sniped by #";
192                         }
193                 }
194         }
195         else if (req == WR_RELOAD)
196         {
197                 W_Campingrifle_Reload();
198         }
199         return TRUE;
200 };