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