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.
5 .float campingrifle_accumulator;
7 float W_CampingRifle_CheckMaxBullets(float checkammo)
10 maxbulls = cvar("g_balance_campingrifle_magazinecapacity");
12 maxbulls = 8; // match HUD
14 if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
15 maxbulls = min(maxbulls, floor(self.ammo_nails / min(cvar("g_balance_campingrifle_primary_ammo"), cvar("g_balance_campingrifle_secondary_ammo"))));
16 if(self.campingrifle_bulletcounter > maxbulls || !cvar("g_balance_campingrifle_magazinecapacity"))
17 self.campingrifle_bulletcounter = maxbulls;
18 return (self.campingrifle_bulletcounter == maxbulls);
21 void W_CampingRifle_ReloadedAndReady()
24 self.campingrifle_bulletcounter = cvar("g_balance_campingrifle_magazinecapacity");
25 W_CampingRifle_CheckMaxBullets(TRUE);
26 t = ATTACK_FINISHED(self) - cvar("g_balance_campingrifle_reloadtime") - 1;
27 ATTACK_FINISHED(self) = t;
31 void W_CampingRifle_Reload()
35 W_CampingRifle_CheckMaxBullets(TRUE);
36 if (self.campingrifle_bulletcounter >= cvar("g_balance_campingrifle_magazinecapacity"))
39 if(self.ammo_nails < min(cvar("g_balance_campingrifle_primary_ammo"), cvar("g_balance_campingrifle_secondary_ammo")))
41 self.campingrifle_bulletcounter = -1; // reload later
45 if (self.weaponentity)
47 if (self.weaponentity.wframe == WFRAME_RELOAD)
50 // allow to switch away while reloading, but this will cause a new reload!
51 self.weaponentity.state = WS_READY;
54 sound (self, CHAN_WEAPON2, "weapons/campingrifle_reload.wav", VOL_BASE, ATTN_NORM);
56 t = max(time, ATTACK_FINISHED(self)) + cvar("g_balance_campingrifle_reloadtime") + 1;
57 ATTACK_FINISHED(self) = t;
59 weapon_thinkf(WFRAME_RELOAD, cvar("g_balance_campingrifle_reloadtime"), W_CampingRifle_ReloadedAndReady);
61 self.campingrifle_bulletcounter = -1;
64 void W_CampingRifle_CheckReloadAndReady()
67 if (self.campingrifle_bulletcounter <= 0)
68 W_CampingRifle_Reload();
73 void W_CampingRifle_FireBullet(float pSpread, float pDamage, float pHeadshotAddedDamage, float pForce, float pSpeed, float pLifetime, float pAmmo, float deathtype, float pBulletConstant)
75 if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
76 self.ammo_nails -= pAmmo;
78 if(deathtype & HITTYPE_SECONDARY)
79 W_SetupShot (self, cvar("g_antilag_bullets") && pSpeed >= cvar("g_antilag_bullets"), 2, "weapons/campingrifle_fire2.wav", cvar("g_balance_campingrifle_secondary_damage"));
81 W_SetupShot (self, cvar("g_antilag_bullets") && pSpeed >= cvar("g_antilag_bullets"), 2, "weapons/campingrifle_fire.wav", cvar("g_balance_campingrifle_primary_damage"));
83 pointparticles(particleeffectnum("shotgun_muzzleflash"), w_shotorg, w_shotdir * 2000, 1);
85 if(self.BUTTON_ZOOM) // if zoomed, shoot from the eye
87 w_shotdir = v_forward;
88 w_shotorg = self.origin + self.view_ofs + ((w_shotorg - self.origin - self.view_ofs) * v_forward) * v_forward;
91 fireBallisticBullet(w_shotorg, w_shotdir, pSpread, pSpeed, pLifetime, pDamage, pHeadshotAddedDamage / pDamage, pForce, deathtype, (cvar("g_balance_campingrifle_tracer") ? EF_RED : EF_BLUE), 1, pBulletConstant);
92 endFireBallisticBullet();
94 if (cvar("g_casings") >= 2)
95 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);
97 self.campingrifle_bulletcounter = self.campingrifle_bulletcounter - 1;
98 W_CampingRifle_CheckMaxBullets(TRUE);
101 void W_CampingRifle_Attack()
103 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"));
106 void W_CampingRifle_Attack2()
108 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"));
111 void spawnfunc_weapon_campingrifle (void)
113 weapon_defaultspawnfunc(WEP_CAMPINGRIFLE);
116 .float bot_secondary_campingriflemooth;
117 float w_campingrifle(float req)
122 self.BUTTON_ATCK=FALSE;
123 self.BUTTON_ATCK2=FALSE;
124 if(vlen(self.origin-self.enemy.origin) > 1000)
125 self.bot_secondary_campingriflemooth = 0;
126 if(self.bot_secondary_campingriflemooth == 0)
128 if(bot_aim(cvar("g_balance_campingrifle_primary_speed"), 0, cvar("g_balance_campingrifle_primary_lifetime"), TRUE))
130 self.BUTTON_ATCK = TRUE;
131 if(random() < 0.01) self.bot_secondary_campingriflemooth = 1;
136 if(bot_aim(cvar("g_balance_campingrifle_secondary_speed"), 0, cvar("g_balance_campingrifle_secondary_lifetime"), TRUE))
138 self.BUTTON_ATCK2 = TRUE;
139 if(random() < 0.03) self.bot_secondary_campingriflemooth = 0;
143 else if (req == WR_THINK)
145 if(self.campingrifle_bulletcounter < 0) // forced reload (e.g. because interrupted)
147 if(self.switchweapon == self.weapon)
148 if(self.weaponentity.state == WS_READY)
149 W_CampingRifle_Reload();
153 self.campingrifle_accumulator = bound(time - cvar("g_balance_campingrifle_bursttime"), self.campingrifle_accumulator, time);
154 if (self.BUTTON_ATCK)
155 if (time >= self.campingrifle_accumulator + cvar("g_balance_campingrifle_primary_burstcost"))
156 if (weapon_prepareattack(0, cvar("g_balance_campingrifle_primary_refire")))
158 W_CampingRifle_Attack();
159 weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_campingrifle_primary_animtime"), W_CampingRifle_CheckReloadAndReady);
160 self.campingrifle_accumulator += cvar("g_balance_campingrifle_primary_burstcost");
162 if (self.BUTTON_ATCK2)
163 if (time >= self.campingrifle_accumulator + cvar("g_balance_campingrifle_secondary_burstcost"))
164 if (weapon_prepareattack(1, cvar("g_balance_campingrifle_secondary_refire")))
166 W_CampingRifle_Attack2();
167 weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_campingrifle_secondary_animtime"), W_CampingRifle_CheckReloadAndReady);
168 self.campingrifle_accumulator += cvar("g_balance_campingrifle_secondary_burstcost");
172 else if (req == WR_PRECACHE)
174 precache_model ("models/weapons/g_campingrifle.md3");
175 precache_model ("models/weapons/v_campingrifle.md3");
176 precache_model ("models/weapons/h_campingrifle.dpm");
177 precache_sound ("weapons/campingrifle_reload.wav");
178 precache_sound ("weapons/campingrifle_fire.wav");
179 precache_sound ("weapons/campingrifle_fire2.wav");
181 else if (req == WR_SETUP)
183 weapon_setup(WEP_CAMPINGRIFLE);
185 full = W_CampingRifle_CheckMaxBullets(TRUE);
186 if(cvar("g_balance_campingrifle_auto_reload_after_changing_weapons"))
188 self.campingrifle_bulletcounter = -1;
190 else if (req == WR_CHECKAMMO1)
191 return self.ammo_nails >= cvar("g_balance_campingrifle_primary_ammo");
192 else if (req == WR_CHECKAMMO2)
193 return self.ammo_nails >= cvar("g_balance_campingrifle_secondary_ammo");
194 else if (req == WR_SUICIDEMESSAGE)
196 if(w_deathtype & HITTYPE_SECONDARY)
197 w_deathtypestring = "shot themself automatically";
199 w_deathtypestring = "sniped themself somehow";
201 else if (req == WR_KILLMESSAGE)
203 if(w_deathtype & HITTYPE_SECONDARY)
205 if(w_deathtype & HITTYPE_BOUNCE)
206 w_deathtypestring = "failed to hide from #'s bullet hail";
208 w_deathtypestring = "died in #'s bullet hail";
212 if(w_deathtype & HITTYPE_BOUNCE)
214 // TODO special headshot message here too?
215 w_deathtypestring = "failed to hide from #'s rifle";
219 if(w_deathtype & HITTYPE_HEADSHOT)
220 w_deathtypestring = "got hit in the head by #";
222 w_deathtypestring = "was sniped by #";
226 else if (req == WR_RELOAD)
228 W_CampingRifle_Reload();
230 else if (req == WR_RESETPLAYER)
232 self.campingrifle_accumulator = time - cvar("g_balance_campingrifle_bursttime");
233 self.campingrifle_bulletcounter = cvar("g_balance_campingrifle_magazinecapacity");
234 W_CampingRifle_CheckMaxBullets(FALSE);