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